nanoPyCodeAgent 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. nanopycodeagent-0.2.0/.agents/skills/land-pr/SKILL.md +85 -0
  2. nanopycodeagent-0.2.0/.agents/skills/release/SKILL.md +89 -0
  3. nanopycodeagent-0.2.0/.agents/skills/release/scripts/verify-release.sh +71 -0
  4. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/.github/workflows/release.yml +7 -3
  5. nanopycodeagent-0.2.0/AGENTS.md +73 -0
  6. nanopycodeagent-0.2.0/CLAUDE.md +1 -0
  7. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/PKG-INFO +32 -1
  8. nanopycodeagent-0.2.0/README.md +82 -0
  9. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/README.zh-CN.md +29 -0
  10. nanopycodeagent-0.2.0/docs/RELEASING.md +33 -0
  11. nanopycodeagent-0.2.0/docs/changelogs/0.1.x.md +32 -0
  12. nanopycodeagent-0.2.0/docs/changelogs/0.2.x.md +23 -0
  13. nanopycodeagent-0.2.0/docs/dev_notes/en/0.2.x.md +24 -0
  14. nanopycodeagent-0.2.0/docs/dev_notes/zh-CN/0.2.x.md +24 -0
  15. nanopycodeagent-0.2.0/docs/superpowers/plans/2026-06-21-release-skills.md +661 -0
  16. nanopycodeagent-0.2.0/docs/superpowers/specs/2026-06-21-release-skill-design.md +240 -0
  17. nanopycodeagent-0.2.0/docs/superpowers/specs/2026-06-29-config-file-support-design.md +124 -0
  18. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/pyproject.toml +11 -1
  19. nanopycodeagent-0.2.0/src/nanopycodeagent/__init__.py +5 -0
  20. nanopycodeagent-0.2.0/src/nanopycodeagent/agent.py +174 -0
  21. nanopycodeagent-0.2.0/tests/test_agent.py +420 -0
  22. nanopycodeagent-0.2.0/uv.lock +350 -0
  23. nanopycodeagent-0.1.0/README.md +0 -52
  24. nanopycodeagent-0.1.0/docs/changelogs/0.1.x.md +0 -25
  25. nanopycodeagent-0.1.0/src/nanopycodeagent/__init__.py +0 -2
  26. nanopycodeagent-0.1.0/uv.lock +0 -7
  27. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/.gitignore +0 -0
  28. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/.python-version +0 -0
  29. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/LICENSE +0 -0
  30. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/docs/changelogs/README.md +0 -0
  31. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/docs/dev_notes/README.md +0 -0
  32. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/docs/dev_notes/en/0.1.x.md +0 -0
  33. {nanopycodeagent-0.1.0 → nanopycodeagent-0.2.0}/docs/dev_notes/zh-CN/0.1.x.md +0 -0
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: land-pr
3
+ description: >
4
+ Use when merging a feature/bugfix PR into main — the everyday, no-release flow.
5
+ Makes the PR self-contained: rewrites the PR description from the PR's own
6
+ contents, appends a changelog [Unreleased] entry when warranted, regenerates the
7
+ English dev notes from the Chinese source when touched, and keeps the bilingual
8
+ README in sync. Then — only after explicit maintainer confirmation — merges the
9
+ PR. Does NOT tag or publish. Triggers on
10
+ "合并 PR / land PR / 合并这个 PR / merge this PR".
11
+ ---
12
+
13
+ # Land a PR
14
+
15
+ Merge a feature/bugfix PR into `main`, making the PR **self-contained** first:
16
+ its code, changelog entry, dev notes (zh + en), and README (zh + en) all in sync
17
+ within the PR. This skill never tags or publishes — that is the `release` skill's job.
18
+
19
+ ## Prerequisites
20
+
21
+ `git` and `gh` (authenticated). See `docs/RELEASING.md`.
22
+
23
+ ## Steps
24
+
25
+ Work on the PR's feature branch (not `main`). `<series>` is the current series
26
+ file, e.g. `docs/changelogs/0.1.x.md` / `docs/dev_notes/{zh-CN,en}/0.1.x.md`.
27
+
28
+ ### 1. Preflight — stop if any check fails
29
+ - `command -v git gh` — present.
30
+ - `gh auth status` — authenticated.
31
+ - `git status --porcelain` — empty (clean tree).
32
+ - current branch is **not** `main` (`git branch --show-current`).
33
+
34
+ ### 2. Ensure a PR exists
35
+ ```bash
36
+ gh pr view --json number,url 2>/dev/null || gh pr create --fill
37
+ ```
38
+ Note the PR number for later steps.
39
+
40
+ ### 3. Append a changelog entry (when warranted)
41
+ Inspect `git diff main...HEAD`. If the changes are worth recording for users, add
42
+ an entry under `## [Unreleased]` in `<series>` (changelogs) in the right group
43
+ (Added / Changed / Fixed / Removed). Purely internal/tooling changes may need
44
+ **no** entry — decide, and surface the decision at the gate.
45
+
46
+ ### 4. Sync English dev notes (if the Chinese source changed)
47
+ If this PR modified `docs/dev_notes/zh-CN/<series>.md`, regenerate the whole
48
+ `docs/dev_notes/en/<series>.md` by translating the Chinese source. The English
49
+ file is generated — do not hand-edit beyond this regeneration.
50
+
51
+ ### 5. Keep the bilingual README in sync
52
+ If this PR changed only one of `README.md` / `README.zh-CN.md`, mirror the change
53
+ into the other (translate/align) so the pair stays consistent. Both READMEs are
54
+ hand-written sources — propose the synced change and let the maintainer adjust the
55
+ wording at the gate; do not blindly overwrite. If both were already changed, skip.
56
+
57
+ ### 6. Commit and push the sync changes
58
+ Commit any changes from steps 3–5 to the feature branch and push:
59
+ ```bash
60
+ git commit -am "docs: sync changelog/dev-notes/README for this PR"
61
+ git push
62
+ ```
63
+ (Skip if steps 3–5 produced no changes.)
64
+
65
+ ### 7. Rewrite the PR description from scratch
66
+ Build the description **only** from the PR's actual contents — commits, changed
67
+ files, `gh pr diff`. **Do not read or extend the old description** (it may be
68
+ stale). Update via the GitHub API (`gh pr edit` can fail on deprecated Projects
69
+ Classic):
70
+ ```bash
71
+ gh api repos/{owner}/{repo}/pulls/{number} -X PATCH -f body="..." --silent
72
+ ```
73
+
74
+ ### 8. ⛔ Confirmation gate (mandatory)
75
+ Present to the maintainer: the rewritten **PR description**, the **changelog
76
+ entry** added (or "none, because …"), and any **dev notes / README sync** done
77
+ (or a README drift warning). **Wait for explicit confirmation** (e.g. "确认 / go").
78
+ Do not merge until approved.
79
+
80
+ ### 9. Merge
81
+ ```bash
82
+ gh pr merge --merge
83
+ ```
84
+ Use the project's existing convention (merge commit; `--squash` only if asked).
85
+ Done — do **not** tag or publish.
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: release
3
+ description: >
4
+ Use when cutting a new release of nanoPyCodeAgent (low-frequency). Does release
5
+ work only — assumes dev notes and README were already kept in sync per-PR by
6
+ land-pr. Picks the next version from the changelog [Unreleased], cuts the
7
+ changelog, then — only after explicit maintainer confirmation — commits the
8
+ changelog straight to main, pushes the vX.Y.Z tag (which triggers the PyPI +
9
+ GitHub Release CI), and verifies the published artifacts via uvx. Triggers on
10
+ "发布 / 发版 / cut a release / publish a release / 打 tag 发版".
11
+ ---
12
+
13
+ # Release
14
+
15
+ Cut and publish a new release of **nanoPyCodeAgent**. This skill does release
16
+ work only; per-PR docs (dev notes, README) are kept in sync by the `land-pr`
17
+ skill, not here.
18
+
19
+ The version is derived from the git tag by `hatch-vcs` — **the tag is the source
20
+ of truth**. Pushing a `v*` tag triggers `.github/workflows/release.yml`
21
+ (`build` → `publish-to-pypi` → `github-release`).
22
+
23
+ ## Prerequisites
24
+
25
+ `git`, `gh` (authenticated), and `uv` installed. See `docs/RELEASING.md`.
26
+
27
+ ## Steps
28
+
29
+ Work entirely on `main`. `<series>` is the current series changelog file,
30
+ e.g. `docs/changelogs/0.1.x.md`.
31
+
32
+ ### 1. Preflight — stop if any check fails
33
+ - `command -v git gh uv` — all present.
34
+ - `gh auth status` — authenticated.
35
+ - `git status --porcelain` — empty (clean tree).
36
+ - `<series>` has entries under `## [Unreleased]`. If empty, there is nothing to
37
+ release — stop.
38
+
39
+ ### 2. Switch to main and update
40
+ ```bash
41
+ git checkout main && git pull --ff-only
42
+ ```
43
+
44
+ ### 3. Decide the version
45
+ Read the entries under `## [Unreleased]` and propose the next semver `X.Y.Z`:
46
+ - a `Removed`/breaking entry → major
47
+ - an `Added` entry → minor
48
+ - only `Fixed` → patch
49
+
50
+ **0.x caveat:** on `0.y.z` a minor may still contain breaking changes; treat the
51
+ proposal as a suggestion. The maintainer makes the final call at the gate (step 5).
52
+
53
+ ### 4. Cut the changelog
54
+ In `<series>`:
55
+ - rename `## [Unreleased]` to `## [X.Y.Z] - <today YYYY-MM-DD>`, keeping its entries;
56
+ - add a fresh empty `## [Unreleased]` section above it.
57
+
58
+ Touch no other file — dev notes and README were synced per-PR by `land-pr`.
59
+
60
+ ### 5. ⛔ Confirmation gate (mandatory)
61
+ Present to the maintainer: the proposed **version** `X.Y.Z` and the **changelog
62
+ diff** (`git diff <series>`). **Wait for explicit confirmation** (e.g. "确认 / go").
63
+ Do not commit, push, or tag until approved. If the version changes, redo step 4.
64
+
65
+ ### 6. Commit and push to main
66
+ ```bash
67
+ git commit -am "Release vX.Y.Z"
68
+ git push origin main
69
+ ```
70
+
71
+ ### 7. Tag and push (triggers the release workflow)
72
+ ```bash
73
+ git tag vX.Y.Z
74
+ git push origin vX.Y.Z
75
+ ```
76
+
77
+ ### 8. Watch the release workflow
78
+ ```bash
79
+ gh run watch
80
+ ```
81
+ Confirm `build` → `publish-to-pypi` → `github-release` succeed. Publish steps are
82
+ idempotent (`--check-url`, `gh release view || create`); a failed run is safe to re-run.
83
+
84
+ ### 9. Verify and report
85
+ ```bash
86
+ .agents/skills/release/scripts/verify-release.sh vX.Y.Z
87
+ ```
88
+ Polls official PyPI for the version, checks the GitHub Release has wheel + sdist,
89
+ and runs a `uvx` smoke test. Report success, or surface the failure verbatim.
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ # verify-release.sh — verify a published nanoPyCodeAgent release.
3
+ #
4
+ # Against the OFFICIAL PyPI index (bypassing any local mirror lag) it checks:
5
+ # 1. the version is present on PyPI
6
+ # 2. a GitHub Release exists for the tag with wheel + sdist assets
7
+ # 3. `uvx ...@VERSION` runs the console entry point (smoke test)
8
+ #
9
+ # Usage: verify-release.sh <version|vVERSION> e.g. verify-release.sh 0.1.1
10
+ #
11
+ # Smoke test runs the entry point with no args (currently side-effect-free).
12
+ # If the entry point ever gains required args/interaction, adjust step 3.
13
+ set -euo pipefail
14
+
15
+ PACKAGE="nanoPyCodeAgent"
16
+ PYPI_JSON="https://pypi.org/pypi/${PACKAGE}/json"
17
+ PYPI_INDEX="https://pypi.org/simple/"
18
+ POLL_TIMEOUT="${VERIFY_TIMEOUT:-300}" # seconds budget per polling stage
19
+ POLL_INTERVAL="${VERIFY_INTERVAL:-15}" # seconds between polls
20
+
21
+ usage() {
22
+ cat <<'EOF'
23
+ Usage: verify-release.sh <version|vVERSION>
24
+
25
+ Verifies a published release against official PyPI + GitHub Release:
26
+ 1. version present on PyPI (pinned to pypi.org, ignores mirrors)
27
+ 2. GitHub Release for the tag has wheel + sdist assets
28
+ 3. uvx smoke test runs the published artifact
29
+
30
+ Env overrides:
31
+ VERIFY_TIMEOUT seconds to wait per polling stage (default 300)
32
+ VERIFY_INTERVAL seconds between polls (default 15)
33
+ EOF
34
+ }
35
+
36
+ if [[ $# -ne 1 ]]; then usage; exit 1; fi
37
+ if [[ "$1" == "-h" || "$1" == "--help" ]]; then usage; exit 0; fi
38
+
39
+ version="${1#v}" # strip leading v -> 0.1.1
40
+ tag="v${version}" # normalized tag -> v0.1.1
41
+
42
+ log() { printf '\n=== %s ===\n' "$*"; }
43
+ fail() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
44
+
45
+ # 1. PyPI presence (poll, pinned to official index) -----------------------
46
+ log "Checking PyPI for ${PACKAGE} ${version}"
47
+ deadline=$(( $(date +%s) + POLL_TIMEOUT ))
48
+ until curl -fsSL "$PYPI_JSON" | grep -q "\"${version}\""; do
49
+ (( $(date +%s) >= deadline )) && fail "version ${version} not on PyPI after ${POLL_TIMEOUT}s"
50
+ printf 'not on PyPI yet; retrying in %ss...\n' "$POLL_INTERVAL"; sleep "$POLL_INTERVAL"
51
+ done
52
+ printf 'OK: %s %s is on PyPI\n' "$PACKAGE" "$version"
53
+
54
+ # 2. GitHub Release + assets ----------------------------------------------
55
+ log "Checking GitHub Release ${tag}"
56
+ gh release view "$tag" >/dev/null 2>&1 || fail "no GitHub Release for ${tag}"
57
+ assets="$(gh release view "$tag" --json assets --jq '.assets[].name')"
58
+ grep -q '\.whl$' <<<"$assets" || fail "Release ${tag} missing a wheel (.whl) asset"
59
+ grep -q '\.tar\.gz$' <<<"$assets" || fail "Release ${tag} missing an sdist (.tar.gz) asset"
60
+ printf 'OK: GitHub Release %s has wheel + sdist\n' "$tag"
61
+
62
+ # 3. uvx smoke test (official index, with retries) ------------------------
63
+ log "Smoke-testing uvx ${PACKAGE}@${version}"
64
+ deadline=$(( $(date +%s) + POLL_TIMEOUT ))
65
+ until uvx --index "$PYPI_INDEX" --from "${PACKAGE}@${version}" "$PACKAGE" >/dev/null 2>&1; do
66
+ (( $(date +%s) >= deadline )) && fail "uvx smoke test failed for ${PACKAGE}@${version} after ${POLL_TIMEOUT}s"
67
+ printf 'uvx not ready (index propagation?); retrying in %ss...\n' "$POLL_INTERVAL"; sleep "$POLL_INTERVAL"
68
+ done
69
+ printf 'OK: uvx smoke test passed for %s@%s\n' "$PACKAGE" "$version"
70
+
71
+ log "Release ${tag} verified ✔"
@@ -33,7 +33,7 @@ jobs:
33
33
  - name: Check distribution metadata
34
34
  run: uvx twine check dist/*
35
35
  - name: Upload artifacts
36
- uses: actions/upload-artifact@v4
36
+ uses: actions/upload-artifact@v7
37
37
  with:
38
38
  name: dist
39
39
  path: dist/
@@ -46,12 +46,16 @@ jobs:
46
46
  id-token: write # required for Trusted Publishing (OIDC)
47
47
  steps:
48
48
  - name: Download artifacts
49
- uses: actions/download-artifact@v4
49
+ uses: actions/download-artifact@v8
50
50
  with:
51
51
  name: dist
52
52
  path: dist/
53
53
  - name: Install uv
54
54
  uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
55
+ with:
56
+ # No checkout in this job, so the cache-dependency glob (pyproject.toml,
57
+ # uv.lock) matches nothing; uv publish needs no resolved-dep cache anyway.
58
+ enable-cache: false
55
59
  - name: Publish to PyPI
56
60
  # --check-url makes re-runs idempotent: files already on the index are
57
61
  # skipped instead of failing the job on "file already exists".
@@ -65,7 +69,7 @@ jobs:
65
69
  contents: write # required to create the release and upload assets
66
70
  steps:
67
71
  - name: Download artifacts
68
- uses: actions/download-artifact@v4
72
+ uses: actions/download-artifact@v8
69
73
  with:
70
74
  name: dist
71
75
  path: dist/
@@ -0,0 +1,73 @@
1
+ # AGENTS.md
2
+
3
+ nanoPyCodeAgent — a nano code agent built from scratch in pure Python.
4
+
5
+ This is the shared project instruction file for coding agents. Codex reads
6
+ `AGENTS.md`; Claude Code reads `CLAUDE.md`, a symlink to this file.
7
+
8
+ ## Skills
9
+
10
+ Project skills live in `.agents/skills/` and are auto-discovered by Codex and pi
11
+ (`.agents/skills/**/SKILL.md`); Claude Code discovers them via `.claude/skills`
12
+ (a symlink to `.agents/skills`). Use a skill by stating intent — the agent loads
13
+ the matching one:
14
+
15
+ - **Landing a PR** (everyday, no release) — merge a feature/bugfix PR into `main`:
16
+ `.agents/skills/land-pr/SKILL.md`
17
+ - **Releasing** (cut a version, publish to PyPI + GitHub):
18
+ `.agents/skills/release/SKILL.md`
19
+
20
+ See `docs/RELEASING.md` for the release process and prerequisites.
21
+
22
+ ## Language
23
+
24
+ Write everything in **English** by default — source code (identifiers,
25
+ comments, string literals), commit messages, PR titles/descriptions, changelog
26
+ entries, and Markdown documentation.
27
+
28
+ The **only** exception is documentation explicitly designated as Chinese:
29
+
30
+ - `README.zh-CN.md` and any other `*.zh-CN.*` file.
31
+ - Files under a `zh-CN/` directory (e.g. `docs/dev_notes/zh-CN/`).
32
+ - Design specs under `docs/superpowers/specs/` — the prose may be Chinese for
33
+ review convenience, but the deliverables the spec produces (code under
34
+ `src/`, tests, and any English documentation) remain English.
35
+ - Any document with an explicit requirement to be written in Chinese.
36
+
37
+ Everything outside that list — including code under `src/`, this file, and all
38
+ other docs — is English.
39
+
40
+ ## Commits & PRs
41
+
42
+ All agents working in this repo MUST follow
43
+ [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
44
+ for **commit messages** and **PR titles** (squash-merge often uses the PR
45
+ title as the commit subject).
46
+
47
+ **Format:**
48
+
49
+ ```
50
+ <type>[optional scope][!]: <description>
51
+
52
+ [optional body]
53
+
54
+ [optional footer(s)]
55
+ ```
56
+
57
+ **Allowed types:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`,
58
+ `test`, `build`, `ci`, `chore`, `revert`.
59
+
60
+ **Rules:**
61
+
62
+ - Description: imperative mood, lowercase, no trailing period.
63
+ - Breaking changes: add `!` after the type/scope and/or include a
64
+ `BREAKING CHANGE:` footer.
65
+ - Separate the optional body and footer(s) from the description with a
66
+ blank line.
67
+
68
+ **Examples:**
69
+
70
+ - `feat: add streaming output to the agent loop`
71
+ - `fix(parser): handle empty tool-call arguments`
72
+ - `docs: require Conventional Commits in AGENTS.md`
73
+ - `refactor!: drop Python 3.9 support` (breaking change)
@@ -0,0 +1 @@
1
+ AGENTS.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nanoPyCodeAgent
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A nano code agent built from scratch in pure Python.
5
5
  Project-URL: Homepage, https://github.com/minixalpha/nanoPyCodeAgent
6
6
  Project-URL: Repository, https://github.com/minixalpha/nanoPyCodeAgent
@@ -13,6 +13,7 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.13
15
15
  Requires-Python: >=3.13
16
+ Requires-Dist: anthropic>=0.112.0
16
17
  Description-Content-Type: text/markdown
17
18
 
18
19
  # nanoPyCodeAgent
@@ -60,6 +61,32 @@ uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@main" nanoPyCodeAg
60
61
  uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@v0.1.0" nanoPyCodeAgent
61
62
  ```
62
63
 
64
+ ### Configuration
65
+
66
+ Credentials and the model come from two sources: **environment variables** and
67
+ an optional user-level config file at `~/.nanoPyCodeAgent/settings.json`.
68
+ Environment variables take precedence — the config file only fills in keys you
69
+ have not set in the environment.
70
+
71
+ The config file mirrors [Claude Code's settings](https://code.claude.com/docs/en/settings):
72
+ put the values under an `env` object. Empty or whitespace-only values are ignored.
73
+
74
+ ```json
75
+ {
76
+ "env": {
77
+ "ANTHROPIC_API_KEY": "",
78
+ "ANTHROPIC_BASE_URL": "",
79
+ "ANTHROPIC_MODEL": ""
80
+ }
81
+ }
82
+ ```
83
+
84
+ | Variable | Required | Default | Description |
85
+ | --- | --- | --- | --- |
86
+ | `ANTHROPIC_API_KEY` | Yes | — | Your Anthropic API key, or the key for a third-party / proxy service. |
87
+ | `ANTHROPIC_BASE_URL` | No | `https://api.anthropic.com` | Point the SDK at a non-official / proxy endpoint. Leave it unset to use the official API — an empty value breaks requests. |
88
+ | `ANTHROPIC_MODEL` | No | `claude-sonnet-4-6` | Override the model. An empty or whitespace-only value falls back to the default. |
89
+
63
90
  ### How to Update
64
91
 
65
92
  Upgrade an installed tool to the latest release:
@@ -67,3 +94,7 @@ Upgrade an installed tool to the latest release:
67
94
  ```bash
68
95
  uv tool upgrade nanoPyCodeAgent # or: pipx upgrade nanoPyCodeAgent
69
96
  ```
97
+
98
+ ## Releasing
99
+
100
+ For maintainers: see [docs/RELEASING.md](docs/RELEASING.md) for the release process and prerequisites.
@@ -0,0 +1,82 @@
1
+ # nanoPyCodeAgent
2
+
3
+ [English](README.md) | [简体中文](README.zh-CN.md)
4
+
5
+ A nano code agent built in pure Python.
6
+
7
+ > "What I cannot create, I do not understand." — Richard Feynman, 1988
8
+
9
+ ## Usage
10
+
11
+ nanoPyCodeAgent requires Python 3.13 or newer.
12
+
13
+ ### How to Run
14
+
15
+ There are a few ways to run it — pick whichever fits your workflow.
16
+
17
+ #### Run without installing
18
+
19
+ Use `uvx` to run the latest release without installing anything:
20
+
21
+ ```bash
22
+ uvx nanoPyCodeAgent
23
+ ```
24
+
25
+ #### Run after installing
26
+
27
+ Install it as a persistent command-line tool, then run it from anywhere:
28
+
29
+ ```bash
30
+ uv tool install nanoPyCodeAgent # or: pipx install nanoPyCodeAgent
31
+ nanoPyCodeAgent
32
+ ```
33
+
34
+ #### Run a branch or tagged version
35
+
36
+ Run an unreleased branch or a specific release tag straight from GitHub:
37
+
38
+ ```bash
39
+ # latest commit on a branch
40
+ uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@main" nanoPyCodeAgent
41
+
42
+ # a specific tag
43
+ uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@v0.1.0" nanoPyCodeAgent
44
+ ```
45
+
46
+ ### Configuration
47
+
48
+ Credentials and the model come from two sources: **environment variables** and
49
+ an optional user-level config file at `~/.nanoPyCodeAgent/settings.json`.
50
+ Environment variables take precedence — the config file only fills in keys you
51
+ have not set in the environment.
52
+
53
+ The config file mirrors [Claude Code's settings](https://code.claude.com/docs/en/settings):
54
+ put the values under an `env` object. Empty or whitespace-only values are ignored.
55
+
56
+ ```json
57
+ {
58
+ "env": {
59
+ "ANTHROPIC_API_KEY": "",
60
+ "ANTHROPIC_BASE_URL": "",
61
+ "ANTHROPIC_MODEL": ""
62
+ }
63
+ }
64
+ ```
65
+
66
+ | Variable | Required | Default | Description |
67
+ | --- | --- | --- | --- |
68
+ | `ANTHROPIC_API_KEY` | Yes | — | Your Anthropic API key, or the key for a third-party / proxy service. |
69
+ | `ANTHROPIC_BASE_URL` | No | `https://api.anthropic.com` | Point the SDK at a non-official / proxy endpoint. Leave it unset to use the official API — an empty value breaks requests. |
70
+ | `ANTHROPIC_MODEL` | No | `claude-sonnet-4-6` | Override the model. An empty or whitespace-only value falls back to the default. |
71
+
72
+ ### How to Update
73
+
74
+ Upgrade an installed tool to the latest release:
75
+
76
+ ```bash
77
+ uv tool upgrade nanoPyCodeAgent # or: pipx upgrade nanoPyCodeAgent
78
+ ```
79
+
80
+ ## Releasing
81
+
82
+ For maintainers: see [docs/RELEASING.md](docs/RELEASING.md) for the release process and prerequisites.
@@ -43,6 +43,31 @@ uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@main" nanoPyCodeAg
43
43
  uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@v0.1.0" nanoPyCodeAgent
44
44
  ```
45
45
 
46
+ ### 配置
47
+
48
+ 凭据与模型有两种配置来源:**环境变量**,以及可选的用户级配置文件
49
+ `~/.nanoPyCodeAgent/settings.json`。环境变量优先级更高——配置文件只用于填补你
50
+ 未在环境变量中设置的键。
51
+
52
+ 配置文件写法与 [Claude Code settings](https://code.claude.com/docs/en/settings)
53
+ 一致:把值放在 `env` 对象下。空值或纯空白会被忽略。
54
+
55
+ ```json
56
+ {
57
+ "env": {
58
+ "ANTHROPIC_API_KEY": "",
59
+ "ANTHROPIC_BASE_URL": "",
60
+ "ANTHROPIC_MODEL": ""
61
+ }
62
+ }
63
+ ```
64
+
65
+ | 变量 | 是否必填 | 默认值 | 说明 |
66
+ | --- | --- | --- | --- |
67
+ | `ANTHROPIC_API_KEY` | 是 | 无 | 你的 Anthropic API key,或第三方/代理服务的 key。 |
68
+ | `ANTHROPIC_BASE_URL` | 否 | `https://api.anthropic.com` | 将 SDK 指向非官方/代理 endpoint。使用官方 API 时保持不设置;留空值会导致请求失败。 |
69
+ | `ANTHROPIC_MODEL` | 否 | `claude-sonnet-4-6` | 覆盖默认模型。空值或纯空白会回退到默认值。 |
70
+
46
71
  ### 如何更新
47
72
 
48
73
  将已安装的工具升级到最新发布版:
@@ -50,3 +75,7 @@ uvx --from "git+https://github.com/minixalpha/nanoPyCodeAgent@v0.1.0" nanoPyCode
50
75
  ```bash
51
76
  uv tool upgrade nanoPyCodeAgent # 或: pipx upgrade nanoPyCodeAgent
52
77
  ```
78
+
79
+ ## 发布
80
+
81
+ 维护者请参阅 [docs/RELEASING.md](docs/RELEASING.md) 了解发布流程与前置条件。
@@ -0,0 +1,33 @@
1
+ # Releasing
2
+
3
+ How nanoPyCodeAgent is maintained and released. Two agent skills drive the flow;
4
+ this document is the human reference.
5
+
6
+ ## Prerequisites (maintainers)
7
+
8
+ - **`uv`** — build / publish / run (`uvx`).
9
+ - **`gh`** — GitHub CLI, authenticated (`gh auth status`).
10
+ - **`git`**.
11
+ - One-time: PyPI Trusted Publishing must be configured for this repo (see the
12
+ header comment in `.github/workflows/release.yml`).
13
+
14
+ ## Two skills
15
+
16
+ | Skill | When | What it does | Publishes? |
17
+ |-------|------|--------------|------------|
18
+ | `land-pr` | Every feature/bugfix PR | Rewrites the PR description, appends a changelog `[Unreleased]` entry when warranted, syncs dev notes (zh→en) and the bilingual README, then merges after confirmation. | No |
19
+ | `release` | Cutting a version | Picks the next version from `[Unreleased]`, cuts the changelog, commits to `main`, pushes the `vX.Y.Z` tag (triggering CI), and verifies PyPI + GitHub Release. | Yes |
20
+
21
+ The changelog flows across both: `land-pr` accumulates entries under
22
+ `[Unreleased]`; `release` turns `[Unreleased]` into a dated version section.
23
+
24
+ ## How it publishes
25
+
26
+ Pushing a `v*` tag triggers `.github/workflows/release.yml`:
27
+ `build` → `publish-to-pypi` (PyPI Trusted Publishing / OIDC) → `github-release`.
28
+ The version is derived from the git tag by `hatch-vcs`.
29
+
30
+ ## Triggering the skills
31
+
32
+ State intent to your agent — "land this PR" / "合并 PR", or "cut a release" /
33
+ "发布". The agent loads the matching skill from `.agents/skills/`.
@@ -0,0 +1,32 @@
1
+ # Changelog — 0.1.x
2
+
3
+ All notable changes in the **0.1.x** release series are documented here.
4
+
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+ - Project-level agent skills `land-pr` and `release` (in `.agents/skills/`, cross-agent: Claude Code / Codex / pi), with a `verify-release.sh` post-publish check, a root `AGENTS.md`, and `docs/RELEASING.md`.
9
+ - Contributing convention: all agents must follow Conventional Commits 1.0.0 for commit messages and PR titles (documented in `AGENTS.md`).
10
+
11
+ ### Changed
12
+ - CI: upgrade the release workflow's artifact actions off the deprecated Node 20 runtime — `actions/upload-artifact` v4 → v7 and `actions/download-artifact` v4 → v8 — and disable the unused `setup-uv` cache in the `publish-to-pypi` job, which has no checkout so its cache-dependency glob matched nothing (#3).
13
+
14
+ ## [0.1.0] - 2026-06-20
15
+
16
+ ### Added
17
+ - uv-managed project with the console-script entry point `nanoPyCodeAgent`.
18
+ - Tag-driven release pipeline: PyPI Trusted Publishing + GitHub Release.
19
+ - Bilingual README (English / 简体中文).
20
+ - changelogs and dev notes
21
+
22
+ <!--
23
+ When cutting a release, copy the relevant items from [Unreleased] into a new
24
+ version section above it, e.g.:
25
+
26
+ ## [0.1.1] - YYYY-MM-DD
27
+
28
+ ### Added
29
+ ### Changed
30
+ ### Fixed
31
+ ### Removed
32
+ -->
@@ -0,0 +1,23 @@
1
+ # Changelog — 0.2.x
2
+
3
+ All notable changes in the **0.2.x** release series are documented here.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.2.0] - 2026-07-09
8
+
9
+ ### Added
10
+ - Interactive agent loop: a multi-turn chatbot built on the Anthropic Python SDK that keeps the full conversation in memory for context and quits on `/exit`.
11
+ - Configurable endpoint, API key, and model via environment variables (`ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL` / `ANTHROPIC_MODEL`) and an optional user-level config file `~/.nanoPyCodeAgent/settings.json`, whose `env` object mirrors [Claude Code's settings](https://code.claude.com/docs/en/settings). Environment variables take precedence; only `ANTHROPIC_*` keys are read, and empty / whitespace-only values are ignored. A missing, unreadable, or malformed config file never blocks startup, and Ctrl-C quits cleanly.
12
+
13
+ <!--
14
+ When cutting a release, copy the relevant items from [Unreleased] into a new
15
+ version section above it, e.g.:
16
+
17
+ ## [0.2.0] - YYYY-MM-DD
18
+
19
+ ### Added
20
+ ### Changed
21
+ ### Fixed
22
+ ### Removed
23
+ -->
@@ -0,0 +1,24 @@
1
+ # Development Notes — 0.2.x
2
+
3
+ > Generated from the Chinese source [`../zh-CN/0.2.x.md`](../zh-CN/0.2.x.md). Do not edit by hand.
4
+
5
+ ## 0.2.0 - 2026.06.29
6
+
7
+ This release implements a minimally functional chatbot that holds a multi-turn conversation with the LLM through the [Messages](https://platform.claude.com/docs/en/api/python/messages/create) API.
8
+
9
+ The LLM's endpoint, key, and model can be configured in two ways:
10
+
11
+ - **Environment variables**: the variable names follow [Claude Code's environment variables](https://code.claude.com/docs/en/env-vars); the three common ones are `ANTHROPIC_API_KEY`, `ANTHROPIC_BASE_URL`, and `ANTHROPIC_MODEL`.
12
+ - **Config file**: located at `~/.nanoPyCodeAgent/settings.json`, with values placed under its `env` field, using the same convention as the `env` field in [Claude Code's settings](https://code.claude.com/docs/en/settings). Example:
13
+
14
+ ```json
15
+ {
16
+ "env": {
17
+ "ANTHROPIC_API_KEY": "",
18
+ "ANTHROPIC_BASE_URL": "",
19
+ "ANTHROPIC_MODEL": ""
20
+ }
21
+ }
22
+ ```
23
+
24
+ The two can be mixed, and **environment variables take precedence over the config file**: when a key is already set in the environment, the config file's value for that same key is ignored; the config file only fills in keys the environment leaves unset. The empty strings in the example are placeholders — empty values (empty or whitespace-only) are skipped.