Skip to content

feat(cli): detect Python projects during init - #270

Open
elMonsi wants to merge 1 commit into
theam:mainfrom
elMonsi:feature/detect-python-projects
Open

feat(cli): detect Python projects during init#270
elMonsi wants to merge 1 commit into
theam:mainfrom
elMonsi:feature/detect-python-projects

Conversation

@elMonsi

@elMonsi elMonsi commented Sep 1, 2026

Copy link
Copy Markdown

What and why

facility init promises to "detect the repository's package manager and checks," but detection in packages/cli/src/detect.mjs only knows the Node ecosystem: it walks pnpm-lock.yaml → yarn.lock → package-lock.json → package.json, derives checks from package.json scripts, and otherwise returns packageManager: "none" with an empty check list and a workflow stub reading "no Node toolchain detected."

That collides with the core argument in concepts/method.md"the environment can't run anything, so verification is impossible, so the agent hedges … the fix is not a better prompt. It is a better job site." Today every Python (and other non-Node) repository begins on exactly that empty job site, so the delivery contract has nothing to bind against.

This change makes Python a first-class detected ecosystem — a first step toward #199, in the shape other stacks can follow.

Changes

  • detect.mjs — when no Node manifest is present, probe for Python (pyproject.toml, requirements.txt, setup.py, setup.cfg, Pipfile):
    • Selects poetry / pipenv / pip and the matching dependency install (poetry install, pipenv install --dev, pip install -r requirements.txt, or pip install -e .).
    • Proposes checks only with configuration evidenceruff/black/mypy tables or config files, and pytest config / a tests/ dir / conftest.py — invoked through the tool's environment (poetry run …, pipenv run …). A dependency merely being present is not treated as proof the team runs it.
    • Reads python-version from .python-version when present (default 3.x).
    • Recognizes Alembic migration layouts (alembic/versions, migrations/versions) for the database-module hint.
  • init.mjstoolchainSteps renders a Python toolchain: a SHA-pinned actions/setup-python@a26af69… (v5) step with python-version quoted so YAML never reads 3.10 as the float 3.1, followed by the tool bootstrap and dependency install.

Node detection is unchanged and takes precedence (a repo with package.json stays a Node repo). No runtime dependency is added — no TOML parser, just presence checks and narrow text probes — and init still asks the operator to confirm every proposed default.

Tests

New packages/cli/test/detect.test.mjs:

  • poetry project → poetry install + poetry run … checks;
  • pip + requirements.txtpip install -r requirements.txt, and a merely-listed tool does not become a check;
  • pip without requirements → pip install -e .;
  • Node detection unchanged (a stray requirements.txt does not flip a Node repo);
  • init renders the pinned, quoted setup-python step and the detected install/check.

Verification

node --test packages/cli/test/detect.test.mjs   # 5/5 pass

Full pnpm verify was not run to completion locally: I'm on Windows, where two pre-existing, unrelated tests fail regardless of this change — the .agents/skills symlink step (#230) and a CRLF line-ending mismatch in the watchtower canary assertion. I confirmed those two failures are identical on a clean checkout (stashing this change), so this PR introduces no regression; CI runs the full suite on Linux.

`facility init` promised to detect a repository's package manager and
checks, but detection only knew the Node ecosystem: a Python repo got
packageManager "none", an empty check list, and a workflow stub reading
"no Node toolchain detected". As the method doc argues, an agent with
nothing to run cannot verify its work, so every non-Node repo began on
exactly the empty job site Facility exists to prevent.

Detect Python as a first-class ecosystem when no Node manifest is present:

- pyproject.toml / requirements.txt / setup.py / setup.cfg / Pipfile select
  poetry, pipenv, or pip, and the matching dependency install command.
- Checks are proposed only with configuration evidence (ruff/black/mypy
  tables or config files; pytest config, a tests/ dir, or conftest.py) and
  invoked through the tool's environment (poetry run / pipenv run).
- The generated workflow renders a SHA-pinned actions/setup-python step,
  python-version quoted so YAML never reads 3.10 as a float, taken from
  .python-version when present.
- Alembic migration layouts feed the database module hint.

Node detection is unchanged and takes precedence. No runtime dependency is
added; init still asks the operator to confirm every proposed default.

Addresses theam#199 for the Python ecosystem; other stacks can follow the same shape.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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