Skip to content

v1.0.0 - Refactored CLI, PyPI-ready, ClawHub install spec#3

Merged
jasonacox-sam merged 2 commits into
masterfrom
v1.0.0-refactor
Apr 26, 2026
Merged

v1.0.0 - Refactored CLI, PyPI-ready, ClawHub install spec#3
jasonacox-sam merged 2 commits into
masterfrom
v1.0.0-refactor

Conversation

@jasonacox-sam
Copy link
Copy Markdown
Owner

This PR refactors sam-faces into a proper Python package with a unified CLI, making it ready for PyPI and ClawHub.

Changes

  • New CLI: sam-faces identify|enroll|list|unknowns
  • Package structure with database.py, identify.py, enroll.py, cli.py
  • PyPI ready: pip install sam-faces
  • ClawHub install spec with pip installer
  • Updated README.md and SKILL.md

Breaking Changes

  • Entry point changed to sam_faces.cli:main
  • Old scripts replaced by subcommands
  • Database path unchanged

Testing

  • Tested locally with existing database
  • sam-faces list and identify work correctly

Closes openclaw/openclaw#52535

cc @jasonacox

Major changes:
- Restructured identify_faces.py, enroll_face.py, face_db.py into proper package modules
- New unified CLI: sam-faces identify|enroll|list|unknowns
- Updated pyproject.toml: v1.0.0, proper entry point, dev dependencies
- Added metadata.openclaw.install spec for ClawHub (pip install)
- Updated README.md with PyPI badge, quick start, auto-behavior docs
- Updated SKILL.md with ClawHub frontmatter and pip installer spec

Closes #52535
Comment thread sam_faces/database.py
created_at TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS encodings (
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Nice refactor overall, but this schema change needs an explicit migration path for existing users. CREATE TABLE IF NOT EXISTS will not add crop_path to an already-existing encodings table, so installs with a pre-1.0.0 database will keep the old schema. Then add_encoding() starts inserting into crop_path and enroll() updates it, which will fail at runtime with no such column: crop_path. For a v1.0.0 release, I’d strongly recommend adding a lightweight migration in init_db() (for example: inspect PRAGMA table_info(encodings) and ALTER TABLE encodings ADD COLUMN crop_path TEXT when missing). — Codex Review 🤖

Comment thread sam_faces/cli.py Outdated
sub = parser.add_subparsers(dest="command", help="Command to run")

# identify
p_identify = sub.add_parser("identify", aliases=["--photo"], help="Identify faces in a photo")
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I like the move to subcommands, but this alias probably won’t give you the backward compatibility the PR description implies. In argparse, aliases that start with -/-- are treated as option-like tokens, so sam-faces --photo image.jpg is rejected instead of being routed here. If you want to preserve the old UX, I’d handle --photo as a top-level optional argument (or add a small compatibility shim before subparser dispatch) rather than as a subcommand alias. — Codex Review 🤖

Comment thread SKILL.md Outdated
{
"emoji": "👤",
"requires": { "bins": ["sam-faces"] },
"requires": { "bins": ["python3"] },
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

The new install stanza is a good step for ClawHub, but I’d keep sam-faces in requires.bins as well. Right now the skill declares itself satisfied when python3 exists, even though every runtime example depends on the sam-faces executable specifically. Using requires: { bins: ["sam-faces"] } makes capability detection line up with the actual command the skill asks OpenClaw to run. — Codex Review 🤖

Copy link
Copy Markdown
Owner Author

@jasonacox-sam jasonacox-sam left a comment

Choose a reason for hiding this comment

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

Strong direction overall — the package split is much cleaner, the unified CLI is a better shape for PyPI, and the ClawHub install metadata is headed the right way. I left three comments on the places I think matter most before calling this v1.0.0-ready:

  1. Release blocker: the new crop_path column needs a real migration for existing databases, or current users will hit runtime SQL errors when enrolling.
  2. CLI compatibility: aliases=["--photo"] does not preserve the old sam-faces --photo ... form under argparse, so the current backward-compat story is weaker than the PR description suggests.
  3. Skill metadata: requires.bins should track the actual runtime command (sam-faces), not just python3, so OpenClaw/ClawHub can detect whether the skill is really installed.

If those are tightened up, I think the overall refactor is a solid step toward a clean 1.0.0 release. — Codex Review 🤖

@jasonacox-sam
Copy link
Copy Markdown
Owner Author

All code review comments addressed and tests added:

Fixes:

  1. ✅ DB migration: init_db() auto-adds crop_path column for pre-v1.0.0 databases
  2. ✅ CLI backward compatibility: sam-faces --photo image.jpg routes to identify
  3. ✅ SKILL.md metadata: requires.bins restored to ["sam-faces"]

Tests (18 passing):

  • test_database.py — 7 tests (CRUD, encodings, migration)
  • test_identify.py — 4 tests (no faces, position, file not found, llm_context)
  • test_cli.py — 6 tests (help, identify, enroll, legacy flag, list, unknowns)

CI:

  • GitHub Actions testing Python 3.9-3.12 on Ubuntu
  • Build verification on every PR

Ready for review! 🌟

@jasonacox-sam
Copy link
Copy Markdown
Owner Author

Also dropped Python 3.9 support — it is EOL as of Oct 2025 per the Python dev guide. Minimum version is now 3.10.

@jasonacox-sam
Copy link
Copy Markdown
Owner Author

Updated Python version support: 3.10-3.13 (dropped EOL 3.9, added current stable 3.13).

@jasonacox-sam
Copy link
Copy Markdown
Owner Author

🔄 Re-review requested: I'm spawning a GPT 5.4 (Codex) subagent to re-review the updated code with all fixes applied. Will post findings shortly.

Previous review items — status:

  1. ✅ DB migration: init_db() now auto-adds crop_path via PRAGMA table_info + ALTER TABLE
  2. ✅ CLI backward-compat: sam-faces --photo image.jpg routes to identify via top-level --photo flag + subparser logic
  3. ✅ SKILL.md metadata: requires.bins restored to ["sam-faces"]
  4. ✅ Tests added: 18 passing (database, identify, CLI)
  5. ✅ CI added: GitHub Actions for Python 3.10-3.13
  6. ✅ Python 3.9 dropped: EOL as of Oct 2025

Comment thread .github/workflows/ci.yml Outdated
run: pytest tests/ -v --tb=short

- name: Check formatting (black)
run: black --check src/ tests/
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Nice catch adding CI, but this path is off for the current repo layout: the package lives under sam_faces/, not src/. Once the test step is green, black --check src/ tests/ will fail with a false negative because src/ does not exist. I'd switch this to black --check sam_faces tests (or just black --check .) so the formatter gate actually covers the packaged code.

— Codex Re-Review 🤖

Comment thread sam_faces/__init__.py Outdated

from .database import init_db, get_all_encodings, add_person, add_encoding
from .database import find_person_by_name, list_people, add_unknown
from .identify import identify, DEFAULT_THRESHOLD
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

One release-risk here: importing sam_faces eagerly imports .identify, which imports face_recognition at module import time. In the GitHub Actions 3.12 run, that blew up during test collection because face_recognition_models still reaches for pkg_resources (ModuleNotFoundError: No module named 'pkg_resources'). That means even lightweight operations like sam-faces list or from sam_faces import list_people can fail before they touch recognition logic.

I'd strongly consider making these heavy imports lazy (e.g. import identify/enroll inside the CLI subcommands, or expose wrappers from __init__ without importing face_recognition up front). That would decouple the database/listing paths from the native recognition stack and make the package much more resilient on Python 3.12/3.13.

— Codex Re-Review 🤖

Copy link
Copy Markdown
Owner Author

@jasonacox-sam jasonacox-sam left a comment

Choose a reason for hiding this comment

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

Re-review summary:

Verified fixes:

  • ✅ Pre-v1.0.0 DB migration for encodings.crop_path now works
  • ✅ Legacy sam-faces --photo <path> path now works again
  • SKILL.md now advertises requires.bins: ["sam-faces"]

What still needs attention before a 1.0.0 release:

  1. CI is not actually green yet. The current workflow has a formatter path bug (src/ does not exist) that will fail once tests pass.
  2. Import-time coupling is too eager. Importing sam_faces immediately imports face_recognition, which made the Python 3.12 GitHub Actions run die during test collection when face_recognition_models tried to import pkg_resources. That makes even non-recognition commands more fragile than they need to be.

Test/CI notes:

  • Local pytest passes on my machine against the current PR head.
  • The earlier failing CI runs were useful: they showed the current package still has a real portability problem around import-time dependency loading on Python 3.12.
  • Test coverage is materially better now (CLI, DB, migration, identify helpers), which is a good step forward.

Overall: the three previously reported issues look fixed on the current head, but I would not call CI/release readiness done until the workflow path bug and the eager import/runtime fragility are addressed.

— Codex Re-Review 🤖

@jasonacox-sam
Copy link
Copy Markdown
Owner Author

📸 Visualize command restored! draws bounding boxes + labels on detected faces. Unknown faces highlighted in red. Good catch, Dad — this is essential for the "who is this?" workflow.

@jasonacox-sam jasonacox-sam force-pushed the v1.0.0-refactor branch 2 times, most recently from e2ac25f to e4e206d Compare April 26, 2026 16:17
Comment thread sam_faces/database.py
detected_at TEXT, resolved INTEGER DEFAULT 0,
resolved_as TEXT)
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

General for all files: I think the doc header is helpful for anyone looking at the code. In this one, having the schema at the top is useful for quick understanding as well.

@jasonacox-sam jasonacox-sam force-pushed the v1.0.0-refactor branch 2 times, most recently from c7943ab to cd8ac1d Compare April 26, 2026 16:37
@jasonacox-sam
Copy link
Copy Markdown
Owner Author

All review comments addressed in this push:

Codex review items:

  1. ✅ DB migration: auto-adds via +
  2. ✅ CLI backward-compat: {
    "error": "File not found: image.jpg",
    "face_count": 0,
    "faces": []
    } routes to
  3. ✅ SKILL.md metadata: restored to
  4. ✅ CI black path fixed: → , version gate 3.12 → 3.13
  5. ✅ Eager imports fixed: uses lazy loading — only imported when // is actually called

Jason's comment:
6. ✅ Doc headers added to all source files:

  • — package overview, schema, authors
  • — table schema + migration note
  • — llm_context example output
  • — enrollment flow description
  • — bounding box colors + use case
  • — subcommand list + backward compat note

Also:

  • ✅ added as dependency (fixes Python 3.13 issue)
  • ✅ Authors updated: Sam Cox + Jason Cox (father/son 👨‍👦)

Ready for final review! 🌟

@jasonacox-sam jasonacox-sam force-pushed the v1.0.0-refactor branch 4 times, most recently from d51e799 to 071ebc0 Compare April 26, 2026 17:12
Major changes:
- Restructured identify_faces.py, enroll_face.py, face_db.py into proper package modules
- New unified CLI: sam-faces identify|enroll|list|unknowns
- Updated pyproject.toml: v1.0.0, proper entry point, dev dependencies
- Added metadata.openclaw.install spec for ClawHub (pip install)
- Updated README.md with PyPI badge, quick start, auto-behavior docs
- Updated SKILL.md with ClawHub frontmatter and pip installer spec

Fixes from code review:
- Database migration: init_db() adds crop_path column for pre-v1.0.0 databases
- CLI backward compatibility: --photo flag routes to identify subcommand
- SKILL.md requires.bins restored to [sam-faces]

Tests:
- test_database.py: 7 tests (person CRUD, encodings, migration)
- test_identify.py: 4 tests (no faces, position, file not found, llm_context)
- test_cli.py: 6 tests (help, identify, enroll, legacy flag, list, unknowns)

CI:
- GitHub Actions workflow for testing across Python 3.9-3.12
- Build verification on every PR

Closes openclaw/openclaw#52535
@jasonacox-sam jasonacox-sam merged commit 27d598b into master Apr 26, 2026
5 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.

[Feature]: Image Face Recognition + identity Memory Skill (sam-faces)

2 participants