cogrind-workshop 0.1.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 (31) hide show
  1. cogrind_workshop-0.1.0/.github/workflows/dev-release.yml +61 -0
  2. cogrind_workshop-0.1.0/.github/workflows/release.yml +134 -0
  3. cogrind_workshop-0.1.0/.github/workflows/reuse.yml +26 -0
  4. cogrind_workshop-0.1.0/.github/workflows/test.yml +38 -0
  5. cogrind_workshop-0.1.0/.github/workflows/version-guard.yml +48 -0
  6. cogrind_workshop-0.1.0/.gitignore +35 -0
  7. cogrind_workshop-0.1.0/.python-version +1 -0
  8. cogrind_workshop-0.1.0/AGENTS.md +29 -0
  9. cogrind_workshop-0.1.0/CHANGELOG.md +24 -0
  10. cogrind_workshop-0.1.0/CLAUDE.md +29 -0
  11. cogrind_workshop-0.1.0/LICENSE +661 -0
  12. cogrind_workshop-0.1.0/LICENSES/AGPL-3.0-or-later.txt +661 -0
  13. cogrind_workshop-0.1.0/LICENSING.md +23 -0
  14. cogrind_workshop-0.1.0/PKG-INFO +58 -0
  15. cogrind_workshop-0.1.0/README.md +43 -0
  16. cogrind_workshop-0.1.0/REUSE.toml +9 -0
  17. cogrind_workshop-0.1.0/cliff.toml +55 -0
  18. cogrind_workshop-0.1.0/docs/CONTRIBUTING.md +71 -0
  19. cogrind_workshop-0.1.0/pyproject.toml +65 -0
  20. cogrind_workshop-0.1.0/scripts/generate_changelog.py +269 -0
  21. cogrind_workshop-0.1.0/src/cogrind_workshop/__init__.py +17 -0
  22. cogrind_workshop-0.1.0/src/cogrind_workshop/__main__.py +10 -0
  23. cogrind_workshop-0.1.0/src/cogrind_workshop/client.py +146 -0
  24. cogrind_workshop-0.1.0/src/cogrind_workshop/formatters.py +236 -0
  25. cogrind_workshop-0.1.0/src/cogrind_workshop/main.py +357 -0
  26. cogrind_workshop-0.1.0/src/cogrind_workshop/repl.py +344 -0
  27. cogrind_workshop-0.1.0/tests/__init__.py +3 -0
  28. cogrind_workshop-0.1.0/tests/conftest.py +14 -0
  29. cogrind_workshop-0.1.0/tests/test_repl.py +315 -0
  30. cogrind_workshop-0.1.0/tests/test_smoke.py +383 -0
  31. cogrind_workshop-0.1.0/uv.lock +790 -0
@@ -0,0 +1,61 @@
1
+ # SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ name: Dev release
6
+
7
+ # On-demand PRE-RELEASE publish from `develop` — a dev build to exercise a candidate
8
+ # before the real release. Manually triggered (workflow_dispatch; run it with
9
+ # `--ref develop`, or via `git dev-release`). Publishes the `X.Y.Z.devN` version to
10
+ # TestPyPI. It creates NO `v*` tag, so the real release.yml gate is untouched, and runs
11
+ # no changelog job. See the handbook's releases.md ("Development versioning") + ci.md.
12
+ #
13
+ # cogrind-workshop is a pure CLI client — TestPyPI only, no GHCR/Docker image (its
14
+ # release.yml has no docker job either).
15
+
16
+ on:
17
+ workflow_dispatch:
18
+
19
+ permissions:
20
+ contents: read
21
+ id-token: write # TestPyPI trusted publishing (OIDC)
22
+
23
+ jobs:
24
+ # Gate: dev builds come from develop and must carry a dev version.
25
+ gate:
26
+ runs-on: ubuntu-latest
27
+ outputs:
28
+ version: ${{ steps.v.outputs.version }}
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+ - name: Verify dev build from develop
32
+ id: v
33
+ run: |
34
+ if [ "$GITHUB_REF" != "refs/heads/develop" ]; then
35
+ echo "dev-release runs from develop only (got $GITHUB_REF)"; exit 1
36
+ fi
37
+ VERSION=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
38
+ case "$VERSION" in
39
+ *.dev*|*-dev) ;;
40
+ *) echo "version '$VERSION' is not a dev version (expected X.Y.Z.devN) — open the dev cycle first"; exit 1 ;;
41
+ esac
42
+ echo "dev version: $VERSION"
43
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
44
+
45
+ testpypi:
46
+ needs: gate
47
+ runs-on: ubuntu-latest
48
+ environment: testpypi # matches the trusted-publisher config on TestPyPI
49
+ steps:
50
+ - uses: actions/checkout@v6
51
+
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v8.1.0
54
+
55
+ - name: Build wheel + sdist
56
+ run: uv build
57
+
58
+ - name: Publish to TestPyPI
59
+ uses: pypa/gh-action-pypi-publish@release/v1
60
+ with:
61
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,134 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ['v*']
6
+
7
+ permissions:
8
+ contents: read
9
+ id-token: write # PyPI trusted publishing
10
+
11
+ # cogrind-workshop is a pure CLI client — PyPI only, no GHCR/Docker image
12
+ # (unlike the MCP-server siblings). The job set is therefore gate → pypi →
13
+ # changelog, with no docker job.
14
+
15
+ jobs:
16
+ # Pre-flight checks. The publish job depends on this, so a failed gate
17
+ # prevents the artifact from shipping (no half-shipped state).
18
+ gate:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v6
22
+ with:
23
+ fetch-depth: 0 # full history needed for the ancestor check below
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v8.1.0
27
+
28
+ - name: Verify tag matches pyproject version
29
+ run: |
30
+ TAG="${GITHUB_REF#refs/tags/v}"
31
+ PROJECT_VERSION=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
32
+ if [ "$TAG" != "$PROJECT_VERSION" ]; then
33
+ echo "tag $TAG != pyproject $PROJECT_VERSION"
34
+ exit 1
35
+ fi
36
+
37
+ - name: Verify tag is reachable from origin/main
38
+ run: |
39
+ git fetch --no-tags origin main
40
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
41
+ echo "tagged commit $GITHUB_SHA is not on origin/main"
42
+ echo "release tags must come from main — back-merge through, then re-tag from main"
43
+ exit 1
44
+ fi
45
+
46
+ pypi:
47
+ needs: gate
48
+ runs-on: ubuntu-latest
49
+ environment: pypi # matches the trusted-publisher config on PyPI
50
+ steps:
51
+ - uses: actions/checkout@v6
52
+
53
+ - name: Install uv
54
+ uses: astral-sh/setup-uv@v8.1.0
55
+
56
+ - name: Build wheel + sdist
57
+ run: uv build
58
+
59
+ - name: Publish to PyPI
60
+ uses: pypa/gh-action-pypi-publish@release/v1
61
+
62
+ # Generate the Highlights paragraph + categorized list, commit the new
63
+ # CHANGELOG.md section back to main, and create the GitHub Release. Runs
64
+ # AFTER pypi so the Release page points at an artifact that already
65
+ # exists. Two-phase invocation of generate_changelog.py keeps the LLM call
66
+ # to a single round-trip even though the commit-back happens onto a fresh
67
+ # main checkout.
68
+ changelog:
69
+ needs: [gate, pypi]
70
+ runs-on: ubuntu-latest
71
+ permissions:
72
+ contents: write # scoped here — only this job commits CHANGELOG.md back to main
73
+ steps:
74
+ - uses: actions/checkout@v6
75
+ with:
76
+ fetch-depth: 0 # full history + all tags for git-cliff
77
+ # default ref = the tag, which is what we want for `--mode=generate`
78
+
79
+ - name: Install uv
80
+ uses: astral-sh/setup-uv@v8.1.0
81
+
82
+ - name: Install git-cliff
83
+ uses: taiki-e/install-action@v2
84
+ with:
85
+ tool: git-cliff
86
+
87
+ - name: Generate release-body.md (LLM call happens here)
88
+ env:
89
+ # Set at the ParkviewLab org level — inherited by every repo
90
+ # under the org. Missing key → script writes a placeholder
91
+ # paragraph and the release still ships.
92
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
93
+ GITHUB_REF: ${{ github.ref }}
94
+ # `uv run --with anthropic` injects the SDK for just this invocation,
95
+ # without polluting pyproject.toml. Lets this workflow snippet be
96
+ # identical across every ParkviewLab repo regardless of whether
97
+ # `anthropic` is otherwise a project dep.
98
+ run: uv run --with anthropic python scripts/generate_changelog.py --mode=generate
99
+
100
+ - name: Switch to fresh origin/main and insert into CHANGELOG.md
101
+ run: |
102
+ # Stash the just-generated release body so it survives the checkout.
103
+ cp release-body.md /tmp/release-body.md
104
+ git fetch origin main
105
+ git checkout origin/main
106
+ mv /tmp/release-body.md release-body.md
107
+ # Re-runs only the file-manipulation half — no LLM call, no anthropic SDK needed.
108
+ uv run python scripts/generate_changelog.py --mode=insert
109
+
110
+ - name: Commit CHANGELOG.md back to main
111
+ run: |
112
+ git config user.name "github-actions[bot]"
113
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
114
+ git add CHANGELOG.md
115
+ if git diff --staged --quiet; then
116
+ echo "no changelog change to commit"
117
+ exit 0
118
+ fi
119
+ TAG="${GITHUB_REF#refs/tags/}"
120
+ # [skip ci] guards against any future non-tag-triggered workflows;
121
+ # this release workflow only fires on `push: tags` so isn't at risk
122
+ # of recursing, but the marker is cheap insurance.
123
+ git commit -m "docs(changelog): $TAG [skip ci]"
124
+ git push origin HEAD:main
125
+
126
+ - name: Create GitHub Release
127
+ env:
128
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
129
+ run: |
130
+ TAG="${GITHUB_REF#refs/tags/}"
131
+ gh release create "$TAG" \
132
+ --title "$TAG" \
133
+ --notes-file release-body.md \
134
+ --target main
@@ -0,0 +1,26 @@
1
+ # SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ name: REUSE
6
+
7
+ # REUSE/SPDX compliance — a required check in every repo (code and docs).
8
+ # See the handbook's licensing.md and ci.md.
9
+
10
+ on:
11
+ pull_request:
12
+ branches: [main, develop]
13
+ push:
14
+ branches: [main, develop]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ reuse:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+ - uses: astral-sh/setup-uv@v8.1.0
25
+ - name: reuse lint
26
+ run: uvx --from "reuse[charset-normalizer]" reuse lint
@@ -0,0 +1,38 @@
1
+ # SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ name: Test
6
+
7
+ on:
8
+ pull_request:
9
+ branches: [main, develop]
10
+ push:
11
+ branches: [main, develop]
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v8.1.0
24
+
25
+ - name: Sync deps
26
+ run: uv sync
27
+
28
+ - name: Lint
29
+ run: uv run ruff check src tests
30
+
31
+ - name: Format check
32
+ run: uv run ruff format --check src tests
33
+
34
+ - name: Type check
35
+ run: uv run ty check # ty must be a dev dependency
36
+
37
+ - name: Tests (excluding network + docling marker)
38
+ run: uv run pytest -m "not integration" -q
@@ -0,0 +1,48 @@
1
+ # SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later
4
+
5
+ name: Version guard
6
+
7
+ # Feature PRs into `develop` must NOT change the version source-of-truth — the
8
+ # bump happens at release, on `main` (see the handbook's releases.md / ci.md).
9
+ # The release back-merge (main→develop) is a direct push, not a PR, so it is not
10
+ # subject to this check.
11
+
12
+ on:
13
+ pull_request:
14
+ branches: [develop]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ no-version-change:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+ with:
25
+ fetch-depth: 0
26
+ - name: Version SoT must be unchanged
27
+ env:
28
+ BASE: ${{ github.base_ref }}
29
+ run: |
30
+ git fetch --no-tags --depth=1 origin "$BASE"
31
+ fail=0
32
+ flag() { echo "::error::$1 changed in a feature PR — version bumps happen at release on main, not in feature work (handbook releases.md)."; fail=1; }
33
+ if [ -f VERSION.txt ]; then
34
+ old=$(git show "origin/$BASE:VERSION.txt" 2>/dev/null || echo "")
35
+ [ "$(cat VERSION.txt)" = "$old" ] || flag VERSION.txt
36
+ fi
37
+ if [ -f pyproject.toml ]; then
38
+ new=$(grep -E '^version *=' pyproject.toml | head -1 || true)
39
+ old=$(git show "origin/$BASE:pyproject.toml" 2>/dev/null | grep -E '^version *=' | head -1 || true)
40
+ [ "$new" = "$old" ] || flag "pyproject.toml [project].version"
41
+ fi
42
+ if [ -f package.json ]; then
43
+ new=$(grep -E '"version"' package.json | head -1 || true)
44
+ old=$(git show "origin/$BASE:package.json" 2>/dev/null | grep -E '"version"' | head -1 || true)
45
+ [ "$new" = "$old" ] || flag "package.json version"
46
+ fi
47
+ if [ "$fail" = 0 ]; then echo "version unchanged ✓"; fi
48
+ exit $fail
@@ -0,0 +1,35 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ *.egg-info/
8
+ *.egg
9
+ .pytest_cache/
10
+ .ruff_cache/
11
+ .ty_cache/
12
+ .mypy_cache/
13
+
14
+ # Build
15
+ build/
16
+ dist/
17
+
18
+ # venv / uv
19
+ .venv/
20
+
21
+ # IDE
22
+ .vscode/
23
+ .idea/
24
+
25
+ # OS
26
+ .DS_Store
27
+ Thumbs.db
28
+
29
+ # Secrets
30
+ .env
31
+ .env.*
32
+
33
+ # Transient release artifact: scripts/generate_changelog.py writes this for
34
+ # `gh release create --notes-file`; it's regenerated every release, never committed.
35
+ release-body.md
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,29 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-or-later
5
+ -->
6
+
7
+ <!-- PARKVIEWLAB:BEGIN (managed by ParkviewLab/handbook — do not edit inside this block; run scripts/sync-agent-files.sh to update) -->
8
+ # ParkviewLab conventions
9
+
10
+ This repo follows the **[ParkviewLab handbook](https://github.com/ParkviewLab/handbook/tree/main)** —
11
+ the single source of truth for how we work. These pointer files **don't re-inline** its rules:
12
+ **read the handbook before non-trivial work**, starting with
13
+ **[`ai-collaboration.md`](https://github.com/ParkviewLab/handbook/blob/main/docs/ai-collaboration.md)**
14
+ (the behavioural contract). Only the safety-critical guardrails are summarized here.
15
+
16
+ **If present, read `docs/northstar.md` before working.** It states the project's intent and is authoritative.
17
+
18
+ ## Shared-state writes need explicit authorization
19
+ - **Merging a PR into `develop` is the user's call.** A broad directive ("fix all that", "finish it") authorizes work on the branch, **not** the merge.
20
+ - **Tagging, cutting a release, force-pushing, or pushing to a protected branch each need an explicit, per-action go-ahead** — never inferred from a descriptive label (e.g. "→ v0.1.1"). One release ask covers the whole CLI release flow.
21
+
22
+ ## Workflow basics
23
+ - Work in an ephemeral, **prefixed** worktree off `develop` (`feature-`/`fix-`/`doc-`/…) — don't commit on `develop`/`main` directly. Open a PR **into `develop`**.
24
+ - PRs are **squash-merged**, so the **PR title** carries the Conventional Commit prefix (`feat:`/`fix:`/`docs:`/…) the changelog is generated from.
25
+
26
+ **Everything else lives in the handbook** (don't rely on memory): branching, commits & changelogs, releases, Python tooling, CI, licensing, and the full communication norms — see <https://github.com/ParkviewLab/handbook/tree/main/docs>.
27
+ <!-- PARKVIEWLAB:END -->
28
+
29
+ <!-- Repo-specific guidance below this line is preserved by the sync script — add anything particular to this repo here. -->
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are recorded here. Each release entry
4
+ has two parts:
5
+
6
+ - **Highlights** — a 2-3 sentence "what's new" paragraph generated at
7
+ release time by an Anthropic-API call (see
8
+ `scripts/generate_changelog.py`).
9
+ - **Categorized changes** — a list of merged commits since the previous
10
+ tag, grouped by [Conventional Commit](https://www.conventionalcommits.org/)
11
+ prefix, produced by [git-cliff](https://git-cliff.org/) using
12
+ `cliff.toml`.
13
+
14
+ The release workflow on every tag push regenerates both, commits the new
15
+ section here, and uses the same content as the GitHub Release body.
16
+
17
+ <!--
18
+ Keep-a-Changelog ordering: [Unreleased] at the top, then newest
19
+ released version, then older versions. generate_changelog.py inserts
20
+ new "## [vX.Y.Z] - YYYY-MM-DD" sections directly below [Unreleased].
21
+ Don't remove the marker.
22
+ -->
23
+
24
+ ## [Unreleased]
@@ -0,0 +1,29 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Gary Frattarola <garyf@parkviewlab.ai>
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-or-later
5
+ -->
6
+
7
+ <!-- PARKVIEWLAB:BEGIN (managed by ParkviewLab/handbook — do not edit inside this block; run scripts/sync-agent-files.sh to update) -->
8
+ # ParkviewLab conventions
9
+
10
+ This repo follows the **[ParkviewLab handbook](https://github.com/ParkviewLab/handbook/tree/main)** —
11
+ the single source of truth for how we work. These pointer files **don't re-inline** its rules:
12
+ **read the handbook before non-trivial work**, starting with
13
+ **[`ai-collaboration.md`](https://github.com/ParkviewLab/handbook/blob/main/docs/ai-collaboration.md)**
14
+ (the behavioural contract). Only the safety-critical guardrails are summarized here.
15
+
16
+ **If present, read `docs/northstar.md` before working.** It states the project's intent and is authoritative.
17
+
18
+ ## Shared-state writes need explicit authorization
19
+ - **Merging a PR into `develop` is the user's call.** A broad directive ("fix all that", "finish it") authorizes work on the branch, **not** the merge.
20
+ - **Tagging, cutting a release, force-pushing, or pushing to a protected branch each need an explicit, per-action go-ahead** — never inferred from a descriptive label (e.g. "→ v0.1.1"). One release ask covers the whole CLI release flow.
21
+
22
+ ## Workflow basics
23
+ - Work in an ephemeral, **prefixed** worktree off `develop` (`feature-`/`fix-`/`doc-`/…) — don't commit on `develop`/`main` directly. Open a PR **into `develop`**.
24
+ - PRs are **squash-merged**, so the **PR title** carries the Conventional Commit prefix (`feat:`/`fix:`/`docs:`/…) the changelog is generated from.
25
+
26
+ **Everything else lives in the handbook** (don't rely on memory): branching, commits & changelogs, releases, Python tooling, CI, licensing, and the full communication norms — see <https://github.com/ParkviewLab/handbook/tree/main/docs>.
27
+ <!-- PARKVIEWLAB:END -->
28
+
29
+ <!-- Repo-specific guidance below this line is preserved by the sync script — add anything particular to this repo here. -->