Import GitHub label synchronization CLI#6
Conversation
Replace the package stub with a Cyclopts CLI that loads TOML label configuration, applies the imported Axinite default labels when no labels are configured, and synchronises labels through github3.py instead of shelling out to `gh`. Add unit, pytest-bdd, and Betamax-backed github3.py coverage for parsing, create/update behaviour, error paths, CLI wiring, and HTTP request flow. Update the users' guide and keep Markdown files formatted so the repository gates pass.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
OverviewThis pull request replaces the generated package stub with a fully functional GitHub label synchronization tool. It imports the Axinite label bootstrap behaviour into a Python package, exposes a Cyclopts-based CLI entrypoint, integrates github3.py for GitHub API access, and makes label names, colours and descriptions configurable through TOML. Label synchronization is kept additive—labels omitted from configuration are not deleted. Core ImplementationConfiguration & Defaults (
Synchronization Engine (
GitHub Integration (
CLI Entrypoint (
Package API (
TestingUnit Tests (
Behaviour Tests (
Integration Tests (
DocumentationUsers' Guide (
Developers' Guide (
Reference & Index (
AGENTS.md Updates:
ConfigurationRuntime Dependencies (
Development Dependencies:
Console Script:
Related IssuesOpen issues for out-of-scope work include property testing with Hypothesis ( WalkthroughImplement a create‑labels CLI: parse TOML into typed configs with defaults, compute effective labels, sync with GitHub via github3.py, add a Cyclopts CLI and packaging entrypoint, and provide unit, BDD and Betamax integration tests plus user/developer documentation. ChangesLabel Configuration and Synchronisation System
Sequence Diagram (high-level sync flow) sequenceDiagram
participant User
participant CLI as create_labels.cli
participant Adapter as create_labels.github
participant GitHub as GitHub API
User->>CLI: invoke `main()` with options (config/repository/token/api_url)
CLI->>CLI: load TOML or use defaults -> LabelConfig
CLI->>Adapter: call `sync_repository_labels(config, repository, token, api_url)`
Adapter->>GitHub: authenticate (github3) and fetch repository
Adapter->>GitHub: GET /repos/{owner}/{repo}/labels/{urlencoded_name} (lookup)
Adapter->>GitHub: POST /repos/{owner}/{repo}/labels (create) or PATCH /repos/{owner}/{repo}/labels/{urlencoded_name} (update)
Adapter-->>CLI: return `LabelSyncResult` tuple
CLI->>User: print "action: name" lines
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 6 warnings)
✅ Passed checks (13 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25f7ac11b0
ℹ️ 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".
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
tests/test_config.py (1)
33-85: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winAdd a regression test for slash-only
github.api_url.Cover the
api_url = "/"case and assertConfigErrorso the normalisation edge case does not regress.🧪 Proposed test
+def test_parse_config_rejects_api_url_empty_after_normalisation() -> None: + """Reject API URLs that normalise to an empty string.""" + with pytest.raises(ConfigError, match="must not be empty after normalisation"): + parse_config({"github": {"api_url": "/"}})🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_config.py` around lines 33 - 85, Add a regression test that ensures a slash-only github.api_url (" / ") is rejected: create a new test (similar to test_load_config_parses_repository_api_url_and_optional_label_fields) that writes a TOML with [github] api_url = "/" (or call parse_config with {"github": {"api_url": "/"}}) and assert it raises ConfigError; reference parse_config and load_config in the test and assert ConfigError to ensure the API URL normalization edge-case is covered.tests/test_sync.py (1)
39-78: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winCollapse mirrored failure-path tests into a parameterized test.
Replace the duplicated failure scaffolding with
@pytest.mark.parametrizeand vary patched callable plus expected error message.As per coding guidelines: "Replace duplicate tests with
@pytest.mark.parametrize".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_sync.py` around lines 39 - 78, Combine the two nearly identical tests into one parameterized test that calls sync_labels with the same LabelSpec but varies the patched callable and expected error message; create a single test (e.g., test_sync_labels_failure_paths) decorated with `@pytest.mark.parametrize` supplying tuples like ("create_label", lambda... returning None, "GitHub did not return a label after creating 'risk: low'") and ("update", lambda... returning False, "GitHub rejected update for label 'risk: low'"), use make_fake_repository/make_fake_label to produce the repository and existing label as needed, monkeypatch.setattr on either repository.create_label or existing.update depending on the parameter, and assert pytest.raises(RuntimeError, match=expected_message) when calling sync_labels with LabelSpec("risk: low", "4CAF50", "Low-risk change").create_labels/github.py (1)
114-145: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd NumPy-style one-line docstrings to private helpers.
Document
_login,_repository_from_env, and_effective_labelswith single-line summaries to keep helper intent explicit and maintainable.♻️ Proposed fix
def _login(token: str | None, api_url: str | None) -> github3.GitHub: + """Authenticate with GitHub using a token and optional API base URL.""" resolved_token = token or os.environ.get("GITHUB_TOKEN") @@ def _repository_from_env() -> RepositorySpec | None: + """Parse ``GITHUB_REPOSITORY`` into a ``RepositorySpec`` when present.""" raw_repository = os.environ.get("GITHUB_REPOSITORY") @@ def _effective_labels(labels: cabc.Sequence[LabelSpec]) -> tuple[LabelSpec, ...]: + """Return configured labels, or defaults when no labels are configured.""" if labels: return tuple(labels) return DEFAULT_LABELSAs per coding guidelines "Docstrings must follow the
numpystyle guide. Use a single-line summary for private functions and methods, and full structured docs for all public interfaces."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@create_labels/github.py` around lines 114 - 145, Add NumPy-style single-line docstrings to the three private helper functions to state their intent: add a one-line summary docstring for _login(token: str | None, api_url: str | None) explaining it resolves token/api URL and returns a GitHub client; for _repository_from_env() explaining it parses GITHUB_REPOSITORY into a RepositorySpec or returns None; and for _effective_labels(labels: cabc.Sequence[LabelSpec]) explaining it returns the provided labels as a tuple or the DEFAULT_LABELS; place each docstring immediately under the def line following numpy single-line convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@create_labels/config.py`:
- Around line 35-85: Update the public class docstrings to full NumPy style:
replace the summary-only docstrings for ConfigError, RepositorySpec, LabelSpec,
and LabelConfig with structured docstrings containing "Parameters" (or
"Attributes" for dataclasses) and "Raises" where applicable; include types and
brief descriptions for RepositorySpec.owner, RepositorySpec.name,
RepositorySpec.full_name (describe it's a property returning "owner/name"),
LabelSpec.name, LabelSpec.color, LabelSpec.description and describe that
LabelSpec.__post_init__ normalises values and may raise ConfigError for empty
names or invalid colours, and document LabelConfig.repository,
LabelConfig.labels, and LabelConfig.api_url. Ensure wording follows NumPy style
and keep private/internal methods single-line only.
- Around line 170-174: The current code validates raw_api_url before trimming
trailing slashes, allowing inputs like "/" to become empty and be returned as
valid; update the logic in create_labels/config.py to first normalize the input
(normalized = raw_api_url.strip().rstrip("/")), then validate that normalized is
a non-empty string (raise ConfigError with the existing message if not) and
finally return normalized; reference the raw_api_url variable, the returned
value, and the ConfigError raised.
In `@create_labels/sync.py`:
- Around line 114-117: The existing code always calls existing_label.update(...)
which causes unnecessary API writes; change sync logic in the block that
currently calls existing_label.update to first compare existing_label's current
name/color/description to the desired label.name, label.color, and
label.description and if they are identical return LabelSyncResult(label.name,
"unchanged") without calling existing_label.update, otherwise proceed to call
existing_label.update and keep the existing RuntimeError-on-failure behavior.
In `@docs/users-guide.md`:
- Line 48: Replace the word "normalised" with the Oxford/en-GB-oxendict spelling
"normalized" in the sentence that reads "may include a leading `#`; they are
normalised to the six-character hex form" so it becomes "may include a leading
`#`; they are normalized to the six-character hex form".
In `@pyproject.toml`:
- Line 25: Replace the floating VCS dependency string "simulacat @
git+https://github.com/leynos/simulacat" with an immutable ref (a specific tag
or commit SHA) so builds are reproducible; update the pyproject.toml entry for
simulacat to include the chosen tag or full commit hash in the VCS URL (e.g.,
using @<tag-or-sha>) and ensure the package identifier remains "simulacat" so
the resolver picks the pinned ref.
In `@tests/steps/test_synchronise_labels.py`:
- Around line 85-89: The two bare assertions in the test should include
descriptive messages to aid debugging: update the assertion that checks for
LabelSpec(name, _HIGH_RISK_COLOR, _HIGH_RISK_DESC) in
label_sync_context["repository"].created to include a message like "expected
created labels to contain {name} with correct color/desc" and update the
assertion that LabelSyncResult(name, "created") in label_sync_context["results"]
to include a message like "expected label sync results to include created result
for {name}"; modify the test assertions referencing LabelSpec,
label_sync_context, and LabelSyncResult accordingly so failures print those
explanatory messages.
- Around line 75-76: Tests use bare assertions at the two checks for
label.updates and label_sync_context results; update both assertions to include
descriptive messages: for the first assertion about label.updates (comparing to
[LabelSpec(name, _LOW_RISK_COLOR, _LOW_RISK_DESC)]) add a message explaining
expected updates (e.g., expected low-risk LabelSpec for name), and for the
second assertion that LabelSyncResult(name, "updated") is in
label_sync_context["results"] add a message clarifying the expected sync result;
locate these in tests/steps/test_synchronise_labels.py referencing
label.updates, LabelSpec, _LOW_RISK_COLOR, _LOW_RISK_DESC, LabelSyncResult and
label_sync_context to modify the assert statements to use the form assert
<condition>, "<descriptive message>".
---
Outside diff comments:
In `@create_labels/github.py`:
- Around line 114-145: Add NumPy-style single-line docstrings to the three
private helper functions to state their intent: add a one-line summary docstring
for _login(token: str | None, api_url: str | None) explaining it resolves
token/api URL and returns a GitHub client; for _repository_from_env() explaining
it parses GITHUB_REPOSITORY into a RepositorySpec or returns None; and for
_effective_labels(labels: cabc.Sequence[LabelSpec]) explaining it returns the
provided labels as a tuple or the DEFAULT_LABELS; place each docstring
immediately under the def line following numpy single-line convention.
In `@tests/test_config.py`:
- Around line 33-85: Add a regression test that ensures a slash-only
github.api_url (" / ") is rejected: create a new test (similar to
test_load_config_parses_repository_api_url_and_optional_label_fields) that
writes a TOML with [github] api_url = "/" (or call parse_config with {"github":
{"api_url": "/"}}) and assert it raises ConfigError; reference parse_config and
load_config in the test and assert ConfigError to ensure the API URL
normalization edge-case is covered.
In `@tests/test_sync.py`:
- Around line 39-78: Combine the two nearly identical tests into one
parameterized test that calls sync_labels with the same LabelSpec but varies the
patched callable and expected error message; create a single test (e.g.,
test_sync_labels_failure_paths) decorated with `@pytest.mark.parametrize`
supplying tuples like ("create_label", lambda... returning None, "GitHub did not
return a label after creating 'risk: low'") and ("update", lambda... returning
False, "GitHub rejected update for label 'risk: low'"), use
make_fake_repository/make_fake_label to produce the repository and existing
label as needed, monkeypatch.setattr on either repository.create_label or
existing.update depending on the parameter, and assert
pytest.raises(RuntimeError, match=expected_message) when calling sync_labels
with LabelSpec("risk: low", "4CAF50", "Low-risk change").
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 32929be9-f086-460e-a315-f2153de477be
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (21)
AGENTS.mdREADME.mdcreate_labels/__init__.pycreate_labels/cli.pycreate_labels/config.pycreate_labels/defaults.pycreate_labels/github.pycreate_labels/pure.pycreate_labels/sync.pydocs/scripting-standards.mddocs/users-guide.mdpyproject.tomltests/features/synchronise_labels.featuretests/fixtures/repository_payload.jsontests/steps/test_synchronise_labels.pytests/test_cli.pytests/test_config.pytests/test_github_betamax.pytests/test_helpers.pytests/test_stub.pytests/test_sync.py
💤 Files with no reviewable changes (4)
- README.md
- tests/test_stub.py
- AGENTS.md
- create_labels/pure.py
Reject slash-only GitHub API URLs after normalization and skip GitHub label updates when existing metadata already matches the desired configuration. Pin the `simulacat` development dependency to an immutable revision, expand public configuration docstrings, and tighten regression coverage for the reviewed sync and parsing paths.
Quote label names before calling `repository.label` so slash-containing names are sent as a single path segment to github3.py. Keep create and update payload names unchanged. Add regression coverage for `scope: channel/cli` and teach the fake repository to resolve encoded lookup path segments.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@create_labels/sync.py`:
- Around line 118-126: Normalize the remote label fields before comparing so the
equality check is idempotent: for existing_label.color remove any leading '#'
and uppercase it (so it matches LabelSpec's uppercase hex) and for
existing_label.description convert null to None and otherwise strip() whitespace
(preserving None when GitHub returns null) then build existing_values from these
normalized values and compare to desired_values; update the equality check
around existing_label, label and LabelSyncResult so unchanged is returned only
when normalized fields match.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: bf779d3b-df3d-4060-8088-1b8ee71ed1f8
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
create_labels/config.pycreate_labels/github.pycreate_labels/sync.pydocs/users-guide.mdpyproject.tomltests/steps/test_synchronise_labels.pytests/test_config.pytests/test_sync.py
Normalize GitHub label colour and description fields before comparing them with `LabelSpec` values. This keeps repeated sync runs idempotent when GitHub returns lowercase colours, leading `#`, or padded descriptions. Add regression coverage for the unchanged path so those formatting differences do not trigger redundant updates.
Document `--config` usage and add a developers guide for the package boundaries, data flow, normalization rules, and local workflow. Extend regression coverage for null GitHub descriptions, GitHub adapter error paths, and all CLI sync result actions. Add private helper docstrings so package docstring coverage includes internal boundaries. Guard the Betamax request recorder with a lock because the mock server records requests from its own thread.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@create_labels/sync.py`:
- Line 107: The private docstring that currently reads "Synchronise one label
and return its action." should use the Oxford -ize spelling; change
"Synchronise" to "Synchronize" so the docstring becomes "Synchronize one label
and return its action." Update the triple-quoted docstring string (the one
containing that exact sentence) in create_labels/sync.py accordingly to match
project docstyle.
In `@docs/developers-guide.md`:
- Line 3: Update the wording in docs/developers-guide.md by replacing the
British-spelled word "summarises" with the Oxford -ize variant "summarizes" on
the line that currently reads "This guide summarises the package structure,
internal boundaries, and local".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 488cae34-7245-48fe-9df8-bd9a462ff6b7
📒 Files selected for processing (8)
create_labels/config.pycreate_labels/sync.pydocs/developers-guide.mddocs/users-guide.mdtests/test_cli.pytests/test_github.pytests/test_github_betamax.pytests/test_sync.py
Add standalone `dependencies`, `github-actions`, and `cargo` labels to the default label set so repositories receive those common automation and package-management labels without custom TOML. Update the default-label regression test to assert the expanded count and the three new label specs explicitly.
|
@coderabbitai Have the following failed checks now been resolved? If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures. Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. ❌ Failed checks (2 errors, 11 warnings)
|
Update the reviewed sync helper docstring and developers guide wording to use the project style-guide -ize spelling.
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix: |
This comment was marked as resolved.
This comment was marked as resolved.
Move github3-specific label lookup handling into the GitHub adapter so the sync module depends only on its repository protocol. Snapshot Betamax-recorded requests under the request lock before assertions and expand the package README and public API module documentation.
Guard the shared Betamax request list with the requested private class lock and snapshot recorded requests under that lock before assertions.
Document the expected validation layers for new features, including `pytest`, `pytest-bdd`, snapshots, end-to-end tests, property tests, and proof-backed contractual logic where appropriate. Clarify where design decisions, user-facing changes, and internal interfaces or practices should be documented.
Ensure the missing-repository test removes `GITHUB_REPOSITORY` so GitHub Actions does not bypass the guard by injecting repository coordinates.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@create_labels/__init__.py`:
- Around line 4-7: The module docstring currently uses British -ise spelling
"synchronisation"; update the docstring to use Oxford -ize spelling by replacing
"synchronisation" with "synchronization" in the public API sentence that
mentions create_labels.sync, and ensure any other occurrences in this docstring
follow the -ize/-yse/-our conventions (e.g., change "synchronisation function"
to "synchronization function" while keeping references to create_labels.config
and create_labels.defaults unchanged).
In `@create_labels/sync.py`:
- Line 13: Update the module-level example sentence that currently reads
"Synchronise two labels against a repository-like object::" to use Oxford -ize
spelling by replacing "Synchronise" with "Synchronize" (i.e., change the
top-level docstring/comment string so it reads "Synchronize two labels against a
repository-like object::"); locate the module-level docstring or top-of-file
comment in the create_labels sync module and make this single-word substitution.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 57de80ef-37ae-4b02-96d3-bdb40352284c
📒 Files selected for processing (8)
AGENTS.mdREADME.mdcreate_labels/__init__.pycreate_labels/github.pycreate_labels/sync.pytests/test_github.pytests/test_github_betamax.pytests/test_sync.py
| re-exports typed configuration values from ``create_labels.config``, the | ||
| imported default label set from ``create_labels.defaults``, and the pure label | ||
| synchronisation function and result type from ``create_labels.sync``. | ||
|
|
There was a problem hiding this comment.
Use Oxford -ize spelling in the module docstring.
Replace synchronisation with synchronization in the public API description.
Triage: [type:spelling] [type:docstyle]
📝 Proposed fix
-... and the pure label synchronisation function and result type from ``create_labels.sync``.
+... and the pure label synchronization function and result type from ``create_labels.sync``.As per coding guidelines: "**/*.py: Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| re-exports typed configuration values from ``create_labels.config``, the | |
| imported default label set from ``create_labels.defaults``, and the pure label | |
| synchronisation function and result type from ``create_labels.sync``. | |
| re-exports typed configuration values from ``create_labels.config``, the | |
| imported default label set from ``create_labels.defaults``, and the pure label | |
| synchronization function and result type from ``create_labels.sync``. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@create_labels/__init__.py` around lines 4 - 7, The module docstring currently
uses British -ise spelling "synchronisation"; update the docstring to use Oxford
-ize spelling by replacing "synchronisation" with "synchronization" in the
public API sentence that mentions create_labels.sync, and ensure any other
occurrences in this docstring follow the -ize/-yse/-our conventions (e.g.,
change "synchronisation function" to "synchronization function" while keeping
references to create_labels.config and create_labels.defaults unchanged).
|
|
||
| Example | ||
| ------- | ||
| Synchronise two labels against a repository-like object:: |
There was a problem hiding this comment.
Use Oxford -ize spelling in the module example sentence.
Replace Synchronise with Synchronize.
Triage: [type:spelling] [type:docstyle]
📝 Proposed fix
-Synchronise two labels against a repository-like object::
+Synchronize two labels against a repository-like object::As per coding guidelines: "**/*.py: Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Synchronise two labels against a repository-like object:: | |
| Synchronize two labels against a repository-like object:: |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@create_labels/sync.py` at line 13, Update the module-level example sentence
that currently reads "Synchronise two labels against a repository-like object::"
to use Oxford -ize spelling by replacing "Synchronise" with "Synchronize" (i.e.,
change the top-level docstring/comment string so it reads "Synchronize two
labels against a repository-like object::"); locate the module-level docstring
or top-of-file comment in the create_labels sync module and make this
single-word substitution.
Add a documentation contents page and repository layout reference so maintainers have clear entrypoints for project guides and source-tree orientation. Reference both documents from `AGENTS.md` as the starting point for documentation and repository context.
Summary
This branch replaces the generated package stub with a working GitHub label synchronization tool. It imports the Axinite label bootstrap behaviour into a Python package, exposes a Cyclopts console entrypoint, uses
github3.pyfor GitHub API access, and makes label names, colours and descriptions configurable through TOML.No issue, roadmap task, or execplan is linked to this branch.
Review walkthrough
github3.pyadapter.Validation
make check-fmt: passedmake typecheck: passedmake lint: passedmake test: passed,16 passedcoderabbit review --agent: passed,findings: 0Notes
github3.py.