Skip to content

Use hyphens, not underscores, in generated GitHub repository URLs - #17

Merged
mariushelf merged 4 commits into
mainfrom
feat/16-loop-use-hyphens-not-underscores-in-generated
Oct 8, 2026
Merged

mariushelf merged 4 commits into
mainfrom
feat/16-loop-use-hyphens-not-underscores-in-generated

Conversation

@mariushelf

Copy link
Copy Markdown
Owner

Generated projects now point their GitHub URLs at the hyphenated repository name, so project_slug = auto_shopper gives github.com/<user>/auto-shopper. The full suite passes (31 tests), and the work is committed with a clean tree. I did not push.

What changed

  • template/pyproject.toml.jinja: the Homepage and Repository URLs use {{ project_slug | replace('_', '-') }}.
  • template/README.md.jinja: the CI badge image and link (line 3) and the "Original repository" link (line 9) use the same expression.
  • tests/test_template.py: a new test, test_github_urls_use_hyphenated_repo_name, runs for both the hexagonal and flat layouts. For each it renders the template without uv sync and checks three things:
    • the pyproject.toml URLs equal https://github.com/testuser/test-project;
    • every github.com/testuser/... URL in README.md uses test-project;
    • no rendered file contains github.com/testuser/test_project.

Test-first check: before the fix, both cases failed on the pyproject.toml URL assertion. After the fix, both pass.

Commits

  • 17a41a4 — test: assert generated GitHub URLs use hyphenated repo name
  • 2be5cb3 — fix: use hyphens in generated GitHub repository URLs

Risk

  • Low. I touched only the three URL lines, so import paths, the src/ package directory and the import-linter contracts still use the underscored slug. The existing import, lint and generated-test checks in the suite pass.
  • Already generated projects are not migrated; copier update picks up the change.
  • No new copier question was added. The repository name is derived from the slug, as the spec assumed.
  • The plan and spec agreed, so there was nothing to reconcile. graphify update . was skipped because this worktree has no graphify-out/.

Fixes #16

~Written by Claude, run via the agentic engineering loop

mariushelf and others added 3 commits October 7, 2026 20:57
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Derive the repository name from project_slug with underscores replaced
by hyphens, as already done for the distribution name. Import paths and
import-linter contracts keep the underscored slug.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@mariushelf

Copy link
Copy Markdown
Owner Author

Build complete.

Cost: build $0.25 (sonnet, effort high) · ticket total $0.78 · API list price

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf left a comment

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.

Review round 1 — approve

Approve. The change pipes project_slug through replace('_', '-') in the GitHub URLs at template/pyproject.toml.jinja:28-29 and template/README.md.jinja:3 and :9. This matches the existing distribution-name derivation. The wheel packages entry, the import-linter contracts and the src/ paths keep the underscored project_slug.

A new parametrized test, test_github_urls_use_hyphenated_repo_name, checks the pyproject URLs and the README URLs. It also scans every rendered file for an underscored repository URL, in the hexagonal layout and in the flat layout.

The riskiest criterion is that the test fails against the old template. Decisive evidence: with the two template files restored from c4ea508, both parametrized cases failed. With the fix in place, the full suite passed, 31 tests.

The diff also adds the loop artifacts plan/issue-16.md and spec/issue-16.md. tasks/pr-comments.md contains no review flags.

Acceptance criteria

  • In a project generated with project_slug = "test_project" and github_username = "testuser", pyproject.toml has Homepage and Repository equal to https://github.com/testuser/test-project.: met
  • In the same project, every github.com/testuser/... URL in README.md uses test-project, and none uses test_project.: met
  • No other generated file contains github.com/<github_username>/<project_slug> with an underscore (checked by grep over the rendered project).: met
  • A test in tests/test_template.py renders the template and asserts the two criteria above, and fails against the current template.: met
  • Python import paths, the package directory under src/, and import-linter contracts still use project_slug with underscores (existing tests stay green).: met

Cost: review $0.36 (opus, effort high) · ticket total $1.14 · API list price

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf added the loop:needs-human Reviewer approved; in human merge queue label Oct 7, 2026
@mariushelf

Copy link
Copy Markdown
Owner Author

Review verdict: approved (tier 0)

~Written by Claude, run via the agentic engineering loop

@mariushelf

Copy link
Copy Markdown
Owner Author

Cost summary (API list price)

Stage Model Effort Attempts Cost
plan opus high 1 $0.53
build sonnet high 1 $0.25
review opus high 1 $0.36
Total 3 $1.14

~Written by Claude, run via the agentic engineering loop

@mariushelf

Copy link
Copy Markdown
Owner Author

/loop fix prefer a new auto-filled variable (not part of the interview) instead of hardcoding the replacement rule in many places.

@mariushelf mariushelf removed the loop:needs-human Reviewer approved; in human merge queue label Oct 8, 2026
@mariushelf

Copy link
Copy Markdown
Owner Author

/loop fix received — re-entering the loop with reset counters.

~Written by Claude, run via the agentic engineering loop

Add a hidden `repo_name` variable to copier.yml (`when: false`, so it is
not asked in the interview and not stored in the answers file), defaulting
to `project_slug | replace('_', '-')`. The GitHub URLs in pyproject.toml
and README.md now use `{{ repo_name }}` instead of repeating the
replacement rule in each place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mariushelf

Copy link
Copy Markdown
Owner Author

Fixer addressed gating findings.

Cost: fix $0.22 (opus, effort default) · ticket total $1.36 · API list price

~Written by Claude, run via the agentic engineering loop

@mariushelf

Copy link
Copy Markdown
Owner Author

The /loop fix work order has been handed to the fixer.

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf left a comment

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.

Review round 1 — approve

Approve. The generated Homepage, Repository, CI badge and "Original repository" URLs now use the hyphenated repository name. The Python package name, the src/ directory and the import-linter contracts keep the underscored project_slug.

The last commit, c32a506, moves the derivation into a hidden copier variable repo_name (when: false). The plan rejected that approach, and the spec assumption names repo_name as a question not to add. A human must accept or revert this design choice. The finding on copier.yml gives the detail.

Decisive evidence for the riskiest criterion: with both template files restored from c4ea508, both cases of test_github_urls_use_hyphenated_repo_name fail. With the change in place, the full suite passes, 31 tests.

Acceptance criteria

  • In a project generated with project_slug = "test_project" and github_username = "testuser", pyproject.toml has Homepage and Repository equal to https://github.com/testuser/test-project.: met
  • In the same project, every github.com/testuser/... URL in README.md uses test-project, and none uses test_project.: met
  • No other generated file contains github.com/<github_username>/<project_slug> with an underscore (checked by grep over the rendered project).: met
  • A test in tests/test_template.py renders the template and asserts the two criteria above, and fails against the current template.: met
  • Python import paths, the package directory under src/, and import-linter contracts still use project_slug with underscores (existing tests stay green).: met

Could not verify

  • Whether the human accepts the hidden repo_name copier variable from c32a506. The spec assumption excludes a repo_name question, and the plan rejected this approach. The owner's call settles it.
  • The spec says that copier update picks the change up. The rendered project has no .copier-answers.yml, so update support looks absent. This change does not cause that. Rendering with an answers-file template would settle it.

Cost: review(2) $0.43 (opus, effort high) · ticket total $1.79 · API list price

~Written by Claude, run via the agentic engineering loop

Comment thread copier.yml
# Computed, not asked: `when: false` hides it from the interview and keeps it
# out of .copier-answers.yml. GitHub repositories are named with hyphens, while
# the Python package name (project_slug) needs underscores.
repo_name:

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.

[minor] The refactor adds a copier variable repo_name, the name the spec assumption excludes. The plan also rejected a hidden when: false variable. The variable is not asked, but --data repo_name=custom-repo overrides it. A render showed custom-repo in the URLs. The override is undocumented, and copier does not save it.
Suggested fix: A human decides. To keep the variable, document the --data override in help or the README. Otherwise revert c32a506 to the inline {{ project_slug | replace('_', '-') }} filter. That filter matches the four existing uses.

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf added the loop:needs-human Reviewer approved; in human merge queue label Oct 8, 2026
@mariushelf

Copy link
Copy Markdown
Owner Author

Review verdict: approved (tier 1)
Could not verify: Whether the human accepts the hidden repo_name copier variable from c32a506. The spec assumption excludes a repo_name question, and the plan rejected this approach. The owner's call settles it.; The spec says that copier update picks the change up. The rendered project has no .copier-answers.yml, so update support looks absent. This change does not cause that. Rendering with an answers-file template would settle it.

~Written by Claude, run via the agentic engineering loop

@mariushelf

Copy link
Copy Markdown
Owner Author

Cost summary (API list price)

Stage Model Effort Attempts Cost
plan opus high 1 $0.53
build sonnet high 1 $0.25
review opus high 2 $0.79
fix opus default 1 $0.22
Total 5 $1.79

~Written by Claude, run via the agentic engineering loop

@mariushelf
mariushelf merged commit ee6dd73 into main Oct 8, 2026
3 checks passed
@mariushelf
mariushelf deleted the feat/16-loop-use-hyphens-not-underscores-in-generated branch October 8, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

loop:needs-human Reviewer approved; in human merge queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use hyphens, not underscores, in generated GitHub repository URLs

1 participant