Imports:
  - Types:
      - resync_registered_agents
    From: goga/connect

Usages:
  convention: .goga/usages/conventions.md
  click: .goga/usages/cooks/click.md

Annotations: |
  The `convention` practice is used for:
  - Working with the codebase
  - Organizing the REPL development cycle
  - Debugging and testing
  - Organizing the test infrastructure
  - Understanding general development and testing principles and rules in the project

  Use the `click` practice to build the upgrade command, its options (--sudo, --user, --tools),
  and exit-code propagation.

  Use `resync_registered_agents` to re-sync every agent recorded in
  ~/.goga/connect.yml after the pip upgrade; this cell only resolves the goga home
  (from $HOME or --user) and passes it through.

  The standard library subprocess, sys, importlib.metadata, pwd, and pathlib modules are used for
  pip invocation, interpreter resolution, tool-package discovery, user HOME resolution, and path handling.

---

"upgrade(use_sudo: bool = False, target_user: str | None = None, include_tools: bool = False) -> exit_code: int":
  location: upgrade.py
  annotations: |
    Upgrade the goga package (and optionally all installed goga_tool_* packages) via pip on the
    current Python interpreter, then re-sync all agents recorded in ~/.goga/connect.yml using their
    per-agent force_overwrite settings.

    `use_sudo`: when True, prepend the sudo command with --preserve-env=HOME flag to the pip command
      (for system-Python installs that require root). Default False.
    `target_user`: when set, resolve ~/.goga/ for this username via pwd.getpwnam(target_user).pw_dir
      instead of $HOME. Used to re-sync another user's goga installation. Default None.
    `include_tools`: when True, additionally upgrade all installed goga_tool_* packages discovered
      via importlib.metadata. Default False.
    `exit_code`: 0 on success, non-zero on pip failure or re-sync failure

    Algorithm:
    1. Build the pip install command:
       a. Base: [sys.executable, "-m", "pip", "install", "goga", "-U"]
       b. If `include_tools` is True: discover installed goga_tool_* packages via
          importlib.metadata.packages_distributions() and append each distribution name
       c. If `use_sudo` is True: prepend ["sudo", "--preserve-env=HOME"] to the command
    2. Run pip via subprocess.run(cmd, check=false)
    3. If pip exits non-zero: emit diagnostics to stderr and return the pip exit code
    4. Resolve the goga home directory for activation:
       a. If `target_user` is set: pwd.getpwnam(target_user).pw_dir / ".goga"
       b. Else: Path.home() / ".goga"
    5. Call `resync_registered_agents` with the resolved goga home; the routine reads the
       registry, re-activates every recorded agent with that agent's force_overwrite, and
       returns 0 on full success (or a missing/empty registry) or the first non-zero per-agent failure
    6. Return the activation outcome

    Apply the `click` practice for command registration, the three options (--sudo/--user/--tools),
    and exit-code propagation via ctx.exit(code).

    Apply the `convention` practice for the CLI command docstring rule (--help
    rendered verbatim by Click; omit Args/Returns/Raises), intra-package imports,
    and structured logging (INFO for upgrade start/finish, WARNING for sudo usage,
    ERROR for pip or re-sync failures).

    Requirements:
    - Always invoke pip via the python -m pip form (never the bare pip executable)
    - When `use_sudo` is True, MUST pass --preserve-env=HOME so the post-pip activation reads
      the correct ~/.goga/
    - When both `use_sudo` and `target_user` are set, `target_user` wins for HOME resolution,
      but pip still runs under sudo
    - `target_user` resolution MUST use pwd.getpwnam (Unix); Windows is documented as a constraint
    - Activation MUST iterate all agents in connect.yml, applying each agent's own force_overwrite;
      a missing connect.yml is a normal condition handled as a 0 result

    Constraints:
    - Do not run pip as a bare subprocess without the python -m prefix
    - Do not read or parse connect.yml directly — delegate activation to `resync_registered_agents`
    - Do not write connect.yml from this cell (goga/connect is the single writer)
    - Windows pwd.getpwnam is unavailable; document as a known constraint
    - This command does NOT auto-detect whether sudo is needed; the user opts in via --sudo

---

Author: Goga
CreatedAt: 28/06/26

Description: |
  CLI wrapper for the goga upgrade command. Combines `pip install goga -U` (optionally with
  goga_tool_* packages and/or sudo) with a post-upgrade re-sync driven by ~/.goga/connect.yml.
