Repository-wide formatting pass over src/ and tests/: sorted imports and
__all__ entries, dropped redundant `# -*- coding: utf-8 -*-` headers,
unquoted forward-reference annotations (safe under
`from __future__ import annotations`), merged nested `with` statements,
moved `Iterable` and friends from `typing` to `collections.abc`, and
removed `# noqa: F401` markers that no longer suppress anything.
No behavioural changes. Unit and integration suites show the same four
pre-existing failures before and after the pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`git init` without `-b` inherits the ambient `init.defaultBranch` config,
which is `master` unless the host has configured otherwise, so `pkgmgr
repos create` produced master-based repositories. On top of that, the
push fallback renamed an already-correct `main` branch back to `master`
whenever the initial push failed (missing remote, auth error).
`init()` now requires an explicit `initial_branch` and runs
`git init -b <branch>`; the bootstrapper passes `main` and no longer
falls back to `master` on push failure.
`resolve_base_branch()` keeps its main -> master fallback, since it reads
existing repositories that may legitimately use master.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pkgmgr code-scanning fetches a repository's GitHub code scanning alerts (and analysis metadata) via the gh CLI and writes alerts.json, a readable summary.md digest, and analyses.json into a timestamped directory (default /tmp/<repo>/code-scanner/<YYYYMMDDHHMMSS>) for offline analysis. The repository is resolved from gh or --repo; authentication is delegated to gh; --state filters by alert state.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The release flow now sanitises the release message into the changelog house style and validates it before writing: a leading '#' heading becomes a bold line, inline `code` becomes *italic*, and the resulting entry is checked with markdownlint-cli2 (using the target repo's own config, i.e. the same rules it enforces) or a built-in fallback. In an interactive run the editor re-opens with the findings until the entry is clean; with --message it transforms then aborts on any finding. The editor's ignore-marker moved from '#' to ';' so heading lines survive as content.
debian/changelog and the RPM %changelog mirror the transformed body, keeping all three changelogs consistent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
update_debian_changelog and update_spec_changelog wrapped the whole release message in a single prefixed line, so only the first line of a multi-line (already-bulleted) message was indented/dashed while the rest stayed at column 0. That made dpkg-parsechangelog emit 'badly formatted heading line' and rpmspec report 'bad date', failing the package build. Each non-empty body line is now indented (Debian) or dash-prefixed (RPM) individually.
update_changelog no longer auto-prepends a '* ' bullet to the CHANGELOG.md entry: the message is inserted verbatim with blank-line separation, so a caller-provided markdown list stays markdown-lint-clean instead of gaining a stray leading bullet.
Adds regression tests for the multi-line debian/rpm mirroring and the no-injected-bullet behaviour.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
update_changelog used to blindly prepend the new ## [version] entry to
the entire file body. When CHANGELOG.md leads with a # Changelog H1
the result was:
## [new] - YYYY-MM-DD
...
# Changelog
## [old] - ...
which trips markdownlint MD041 (first-line-h1) and MD012
(no-multiple-blanks), and reads as if the document were two stacked
changelogs.
The new _insert_after_h1 helper:
* Synthesises # Changelog when the file is empty.
* Inserts the entry between the existing H1 (plus any intro prose)
and the first existing ## release entry.
* For legacy headerless files (file starts with ##) prepends the
synthesised H1 + entry, so the resulting document is also
MD041-clean.
Tests cover the three layouts (empty, H1+existing-entries,
legacy-headerless). All 61 release-unit tests stay green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Walks a directory of numbered NNN-topic.md files, promotes every file
with zero unchecked task-list items into the directorys README under
the ## Archive section, then deletes the source file. Keeps spec
directories (typically docs/requirements) short and focused on open
work.
The action ships as pkgmgr.actions.archive with four leaf modules
(discovery, inspect, readme, workflow) and is wired into the CLI as
pkgmgr archive [DIR] [--readme PATH] [--dry-run] [--include-template].
Extracted verbatim from cli/contributing/requirements/archive in
infinito-nexus-core so every kpmx-managed repository can rely on the
same archival convention without copy-pasting helpers. Twenty unit
tests cover discovery, inspection, README merge, and end-to-end
workflow paths.
Also: realign tests/unit/pkgmgr/cli/commands/test_release.py with the
new run_release(retry=False) signature shipped in v1.14.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Recovers from a release whose tag+commit landed cleanly but whose
post-tag steps (git push, latest-tag bump, twine upload) failed
mid-flight. pkgmgr release --retry skips the version bump, file
rewrites, commit, and tag-creation steps and re-runs only the
idempotent tail: re-push the existing HEAD tag, re-align the floating
latest tag, and (unless --no-publish) re-invoke publish.
The retry logic lives in its own module pkgmgr.actions.release.retry
so the workflow.py orchestrator stays focused on the forward path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously the release workflow derived the distro-package name from
`os.path.basename(repo_root)`. Renaming the repo folder (e.g.
`infinito-nexus` → `infinito-nexus-core`) silently rewrote
`debian/changelog`'s top entry to the new folder name while
`debian/control` still pinned the legacy `Package:` value. dpkg-source
refuses to build a source package when the two disagree.
Add `resolve_package_name(paths)` that consults the existing packaging
files in priority order (debian/control `Package:` → PKGBUILD
`pkgname=` → RPM `.spec` `Name:`) and only falls back to the folder
basename when no packaging metadata is present. Extend `RepoPaths`
with a `debian_control` slot so `resolve_repo_paths` can discover the
file under both `packaging/debian/control` and the legacy `debian/`
location.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Restrict setuptools package discovery to src/ (pkgmgr* only)
- Drop config/ as a Python package mapping (keep config as plain data dir)
- Remove config_defaults fallback paths and use config/ exclusively
- Add unit + integration tests for defaults.yaml loading and CLI update copying
https://chatgpt.com/share/6947e74f-573c-800f-b93d-5ed341fcd1a3
* Add mirror visibility subcommand and provision --public flag
* Implement core visibility API with provider support (GitHub, Gitea)
* Extend provider interface and EnsureStatus
* Add unit, integration and e2e tests for visibility handling
https://chatgpt.com/share/6946a44e-4f48-800f-8124-9c0b9b2b6b04
- Add probe_remote_reachable_detail and improved GitRunError metadata
- Print short failure reasons for unreachable remotes
- Provision each git mirror URL via ensure_remote_repository_for_url
https://chatgpt.com/share/6946956e-f738-800f-a446-e2c8bf5595f4
- Adjust tests to expect RuntimeError instead of SystemExit
- Add coverage for missing [project] section in pyproject.toml
- Keep spec macro %{?dist} intact in test fixtures
- Minor cleanup and reformatting of test cases
https://chatgpt.com/share/69454836-4698-800f-9d19-7e67e8e789d6
* Replace legacy GitError usage with a clearer exception hierarchy:
* GitBaseError as the common root for all git-related failures
* GitRunError for subprocess execution failures
* GitQueryError for read-only query failures
* GitCommandError for state-changing command failures
* GitNotRepositoryError to explicitly signal “not a git repository” situations
* Update git runner to detect “not a git repository” stderr and raise GitNotRepositoryError with rich context (cwd, command, stderr)
* Refactor repository verification to use dedicated query helpers instead of ad-hoc subprocess calls:
* get_remote_head_commit (ls-remote) for pull mode
* get_head_commit for local mode
* get_latest_signing_key (%GK) for signature verification
* Add strict vs best-effort behavior in verify_repository:
* Best-effort collection for reporting (does not block when no verification config exists)
* Strict retrieval and explicit error messages when verification is configured
* Clear failure cases when commit/signing key cannot be determined
* Add new unit tests covering:
* get_latest_signing_key output stripping and error wrapping
* get_remote_head_commit parsing, empty output, and error wrapping
* verify_repository success/failure scenarios and “do not swallow GitNotRepositoryError”
* Adjust imports and exception handling across actions/commands/queries to align with GitRunError-based handling while keeping GitNotRepositoryError uncaught for debugging clarity
https://chatgpt.com/share/6943173c-508c-800f-8879-af75d131c79b
* Move VS Code workspace logic (incl. guards) from cli.commands.tools into cli.tools.vscode
* Extract shared repo path resolution into cli.tools.paths and reuse for explore/terminal
* Simplify cli.commands.tools to pure orchestration via open_vscode_workspace
* Update existing tools command unit test to assert delegation instead of patching removed internals
* Add new unit tests for cli.tools.paths and cli.tools.vscode (workspace creation, reuse, guard errors)
https://chatgpt.com/share/69419a6a-c9e4-800f-9538-b6652b2da6b3
- Treat MIRRORS as the only authority for mirror URLs
- Filter non-git URLs (e.g. PyPI) from git remotes and push URLs
- Prefer SSH git URLs when determining primary origin
- Ensure mirror probing only targets valid git remotes
- Refactor repository create into service-based architecture
- Write PyPI metadata exclusively to MIRRORS, never to git config
- Add integration test verifying PyPI is not written into .git/config
- Update preview and unit tests to match new create flow
https://chatgpt.com/share/69415c61-1c5c-800f-86dd-0405edec25db
- Replace direct subprocess usage with core.git.run wrapper
- Introduce dedicated core.git.commands (add, commit, fetch, pull_ff_only, push, clone, tag_annotated, tag_force_annotated, etc.)
- Introduce core.git.queries (list_tags, get_upstream_ref, get_config_value, changelog helpers, etc.)
- Refactor release workflow and git_ops to use command/query split
- Implement semantic vX.Y.Z comparison with safe fallback for non-parseable tags
- Refactor repository clone logic to use core.git.commands.clone with preview support and ssh→https fallback
- Remove legacy run_git_command helpers
- Split and update unit tests to mock command/query boundaries instead of subprocess
- Add comprehensive tests for clone modes, preview behavior, ssh→https fallback, and verification prompts
- Add unit tests for core.git.run error handling and preview mode
- Align public exports (__all__) with new structure
- Improve type hints, docstrings, and error specificity across git helpers
https://chatgpt.com/share/69414735-51d4-800f-bc7b-4b90e35f71e5
- Remove legacy shell-based git helpers from release workflow
- Introduce typed git command wrappers (add, commit, fetch, pull_ff_only, push, tag*)
- Add git queries for upstream detection and tag listing
- Refactor release workflow to use core git commands consistently
- Implement semantic vX.Y.Z tag comparison without external sort
- Ensure prerelease tags (e.g. -rc) do not outrank final releases
- Split and update unit tests to match new command/query architecture
- Update mirror integration tests to use probe_remote_reachable
- Refactor branch action tests to mock git command helpers instead of run_git
- Align changelog tests with get_changelog query API
- Update git core tests to cover run() and query helpers
- Remove legacy run_git assumptions from tests
https://chatgpt.com/share/69412008-9e8c-800f-9ac9-90f390d55380
**Validated by Google's model.**
**Summary:**
The test modifications have been correctly implemented to cover the Git refactoring changes:
1. **Granular Mocking:** The tests have shifted from mocking the monolithic `run_git` or `subprocess` to mocking the new, specific wrapper functions (e.g., `pkgmgr.core.git.commands.fetch`, `pkgmgr.core.git.queries.probe_remote_reachable`). This accurately reflects the architectural change in the source code where business logic now relies on these granular imports.
2. **Structural Alignment:** The test directory structure was updated (e.g., moving tests to `tests/unit/pkgmgr/core/git/queries/`) to match the new source code organization, ensuring logical consistency.
3. **Exception Handling:** The tests were updated to verify specific exception types (like `GitDeleteRemoteBranchError`) rather than generic errors, ensuring the improved error granularity is correctly handled by the CLI.
4. **Integration Safety:** The integration tests in `test_mirror_commands.py` were correctly updated to patch the new query paths, ensuring that network operations remain disabled during testing.
The test changes are consistent with the refactor and provide complete coverage for the new code structure.
https://aistudio.google.com/app/prompts?state=%7B%22ids%22:%5B%2214Br1JG1hxuntmoRzuvme3GKUvQ0heqRn%22%5D,%22action%22:%22open%22,%22userId%22:%22109171005420801378245%22,%22resourceKeys%22:%7B%7D%7D&usp=sharing
- Resolve primary remote via RepoMirrorContext (origin → file order → config → default)
- Always set origin fetch and push URL to primary
- Add additional mirrors as extra push URLs without duplication
- Update remote provisioning and setup commands to use context-based resolution
- Adjust and extend unit tests to cover new origin/push behavior
https://chatgpt.com/share/693f4538-42d4-800f-98c2-2ec264fd2e19
- Run publish automatically after successful release
- Add --no-publish flag to disable auto-publish
- Respect TTY for interactive/credential prompts
- Harden repo directory resolution
- Add integration and unit tests for release→publish hook
https://chatgpt.com/share/693f335b-b820-800f-8666-68355f3c938f
* Introduce publish action with PyPI target detection via MIRRORS
* Resolve version from SemVer git tags on HEAD
* Support preview mode and non-interactive CI usage
* Build and upload artifacts using build + twine with token resolution
* Add CLI wiring (dispatch, command handler, parser)
* Add E2E publish help tests for pkgmgr and nix run
* Add integration tests for publish preview and mirror handling
* Add unit tests for git tag parsing, PyPI URL parsing, workflow preview, and CLI handler
* Clean up dispatch and parser structure while integrating publish
https://chatgpt.com/share/693f0f00-af68-800f-8846-193dca69bd2e
- Move Nix flake installer into installers/nix/ with atomic components
(installer, runner, profile, retry, types)
- Preserve legacy behavior and semantics of NixFlakeInstaller
- Add GitHub API 403 rate-limit retry with Fibonacci backoff + jitter
- Update all imports to new nix module path
- Rename legacy unit tests and adapt patches to new structure
- Add unit test for simulated GitHub 403 retry without realtime sleeping
https://chatgpt.com/share/693e925d-a79c-800f-b0b6-92b8ba260b11
- Adapt DummyCtx to include quiet and force_update flags
- Replace os.system mocking with run_command/subprocess mocks
- Align assertions with new Nix install/upgrade output
- Keep coverage for mandatory vs optional output handling
https://chatgpt.com/share/693db645-c420-800f-b921-9d5c0356d0ac
- Fix undefined repo_dir usage in repository deinstall action
- Centralize and harden get_repo_dir with strict validation and clear errors
- Expand user paths for repository base and binary directories
- Add unit tests for get_repo_dir and deinstall_repos
- Add comprehensive tests for resolve_repos identifier matching
- Remove obsolete command resolution tests no longer applicable
https://chatgpt.com/share/693d7442-c2d0-800f-9ff3-fb84d60eaeb4
Switch run_command to a single-run execution model that streams stdout/stderr
live while capturing both streams in memory using selectors. This guarantees
that command errors (e.g. make install, pip, nix) always show full diagnostics
without re-running commands or risking deadlocks.
Add unit tests for preview mode, success execution, failure handling, and
allow_failure behavior.
Context:
https://chatgpt.com/share/replace-with-this-conversation-link
* Treat remote tags as the source of truth by force-fetching tags from *origin*
* Update preview output to reflect the real fetch behavior
* Align unit tests with the new forced tag fetch command
https://chatgpt.com/share/693bdfc3-b8b4-800f-8adc-b1dc63c56a89
* Add debug output for latest vs current version tag in release git ops
* Treat “no version tags yet” as highest by definition
* Align unit tests with current *string-based* `tag >= latest` behavior
* Make tag listing mocks less brittle by matching command patterns
* Rename release init test to `test_init.py` for consistent discovery
Refactor the release implementation into a dedicated workflow module with clear separation of concerns. Enforce a safe, deterministic Git flow by always syncing with the remote before modifications, pushing only the current branch and the newly created version tag, and updating the floating *latest* tag only when the released version is the highest. Add explicit user prompts for confirmation and optional branch deletion, with a forced mode to skip interaction. Update CLI wiring to pass all relevant flags, add comprehensive unit tests for the new helpers and workflow entry points, and introduce detailed documentation describing the release process, safety rules, and execution flow.
The old test tests/unit/pkgmgr/actions/test_branch.py has been removed because:
- it targeted the previous monolithic pkgmgr.actions.branch module structure
- its patch targets no longer match the refactored code
- its responsibilities are now fully covered by the new, dedicated unit,
integration, and E2E tests for branch actions and CLI wiring
This avoids redundant coverage and prevents misleading or broken tests
after the branch refactor.
https://chatgpt.com/share/693bcc8d-b84c-800f-8510-8d6c66faf627
This commit removes the `run_command`-based execution model for Nix flake
installations and replaces it with a direct `os.system` invocation.
This ensures that *all* Nix diagnostics (stdout/stderr) are fully visible and
no longer suppressed by wrapper logic.
Key changes:
* Directly run `nix profile install` via `os.system` for full error output
* Correctly decode real exit codes via `os.WIFEXITED` / `os.WEXITSTATUS`
* Preserve mandatory/optional behavior for flake outputs
* Update unit tests to the new execution model using `unittest`
* Add complete coverage for:
* successful installs
* mandatory failures → raise SystemExit(code)
* optional failures → warn and continue
* environment-based disabling via `PKGMGR_DISABLE_NIX_FLAKE_INSTALLER`
* Remove obsolete mocks and legacy test logic that assumed `run_command`
Overall, this improves transparency, debuggability, and correctness of the
Nix flake installer while maintaining full backward compatibility at the
interface level.
https://chatgpt.com/share/693b0a20-99f4-800f-b789-b00a50413612
- Introduce explicit CLI layer model (os-packages, nix, python, makefile)
and central InstallationPipeline to orchestrate installers.
- Move installer orchestration out of install_repos() into
pkgmgr.actions.repository.install.pipeline, using layer precedence and
capability tracking.
- Add pkgmgr.actions.repository.install.layers to classify commands into
layers and compare priorities.
- Rework PythonInstaller to always use isolated environments:
PKGMGR_PIP override → active venv → per-repo venv under ~/.venvs/<identifier>,
avoiding system Python and PEP 668 conflicts.
- Adjust NixFlakeInstaller to install flake outputs based on repository
identity: pkgmgr/package-manager → pkgmgr (mandatory) + default (optional),
all other repos → default (mandatory).
- Tighten MakefileInstaller behaviour, add global
PKGMGR_DISABLE_MAKEFILE_INSTALLER switch, and simplify install target
detection.
- Rewrite resolve_command_for_repo() with explicit Repository typing,
better Python package detection, Nix/PATH resolution, and a
library-only fallback instead of raising on missing CLI.
- Update flake.nix devShell to provide python3 with pip and add pip as a
propagated build input.
- Remove deprecated/wip repository entries from config defaults and drop
the unused config/wip.yml.
https://chatgpt.com/share/69399157-86d8-800f-9935-1a820893e908
This update introduces Variant B behavior in the command resolver:
- If a repository explicitly defines the key \"command\" (even if its value is None),
resolve_command_for_repo() treats it as authoritative and returns immediately.
This allows library-only repositories to declare:
command: null
which disables CLI resolution entirely.
- As a result, Python package repositories without installed CLI entry points
no longer trigger SystemExit during update/install flows, as long as they set
command: null in their repo configuration.
The resolution logic is now bypassed for such repositories, skipping:
- Python package detection (src/*/__main__.py)
- PATH/Nix/venv binary lookup
- main.sh/main.py fallback evaluation
A new unit test suite has been added under
tests/unit/pkgmgr/core/command/test_resolve.py
covering:
1) Python package without installed command → SystemExit
2) Python package with installed command → returned correctly
3) Script repository fallback to main.py
4) Explicit command overrides all logic
This commit stabilizes update/install flows and ensures library-only
repositories behave as intended when no CLI command is provided.
https://chatgpt.com/share/69394a53-bc78-800f-995d-21099a68dd60