semvec/pypi-packages huggingface dataset:
gh-task 0.1.7
Python + CLI helpers for GitHub Projects task ownership
License: MIT
Requires Python: >=3.9

# gh-task

Python + CLI helpers for taking, moving, and releasing GitHub Project (v2) issues using a lightweight ownership label protocol.

## Install (local)

```bash
pip install -e .
```

## Prerequisites

`gh` must be installed and authenticated (the library uses it to fetch a token if no `GH_TOKEN`/`GITHUB_TOKEN` is set).

## Auth

Uses `GH_TOKEN` or `GITHUB_TOKEN` if set, otherwise falls back to `gh auth token`. Ensure the token has the `project` scope for Project v2 access.

## Python usage

```python
from gh_task import Project

project = Project(
    project="https://github.com/users/yieldthought/projects/3/views/1",
    name="my-name",
    has_label=["bug", "help wanted"],
)

# list status columns (project can be a short ref or full URL)
print(project.list())

# list issue numbers in Backlog
print(project.list("Backlog"))

# take a specific issue (number, URL, or owner/repo#number)
issue_id = project.take(2)

# take the first available issue in Backlog that matches the label filter
issue_id = project.take("Backlog")

# move and release
project.move(2, "In review")
project.release(2)

# context-managed lease (auto-release on exit)
with project.lease("Backlog") as issue:
    print(issue.number)

# create a new issue and add it to the project
issue = project.create(
    title="Investigate latency spikes",
    description="See logs from Jan 24",
    status="Backlog",
    repo="yieldthought/gh-task",  # optional if the project has a single repo
    label="bug",
)
```

## CLI

```bash
# list status columns
 gh-task list -p yieldthought/projects/3 -n my-name

# list issues in Backlog
 gh-task list -p yieldthought/projects/3 -n my-name Backlog

# take a specific issue
 gh-task take -p yieldthought/projects/3 -n my-name -i 2

# take the first available issue in Backlog
 gh-task take -p yieldthought/projects/3 -n my-name -l "bug,help wanted" Backlog

# move and release
 gh-task move -p yieldthought/projects/3 -n my-name -i 2 -s "In review"
 gh-task release -p yieldthought/projects/3 -n my-name -i 2

# create a new issue and add it to the project (repo inferred if possible)
 gh-task create -p yieldthought/projects/3 -r yieldthought/gh-task -t "Fix retry logic" -d "Add jitter + cap"
 gh-task create -p yieldthought/projects/3 -t "Investigate latency spikes" -s Backlog --label bug
```

## Label filtering

`has_label` (or `--label/-l`) restricts `.list()` and `.take()` to issues that carry at least one of the provided labels.
When taking a specific issue, a `TakeError` is raised if it does not match the filter.

## Ownership protocol

`take()` performs the following:
1. Verify there is no label starting with `owner:`.
2. Add a comment `Taking: <name>`.
3. Wait 1s (configurable) and fetch all comments beginning with `Taking:`.
4. If the earliest `Taking:` comment is yours, add `owner: <name>` label.
5. Remove your `Taking:` comment (best-effort).

If any step fails, the comment is removed and a `TakeError` is raised.
tarnished 0.2.1
File state checkpoint tool - has your code tarnished?
License: MIT
Requires Python: >=3.11
Keywords: checkpoint, checksum, cli, development, file-state, verification

# tarnished

File state checkpoint tool - has your code tarnished?

## Installation

### Using uv (recommended)

```bash
uv tool install tarnished
```

### Using pip

```bash
pip install tarnished
```

### From source

```bash
git clone https://github.com/RasmusGodske/tarnished.git
cd tarnished
uv tool install .
```

## Quick Start

```bash
# Initialize .tarnished/ directory
tarnished init

# Save a checkpoint for a profile
tarnished save lint:php "app/**/*.php" "tests/**/*.php"

# Check if files have changed
tarnished check lint:php  # Exit 0 = clean, Exit 1 = tarnished

# See status of all profiles
tarnished status
```

## Usage

### Commands

| Command | Description |
|---------|-------------|
| `tarnished init` | Initialize .tarnished/ directory |
| `tarnished save <profile> [patterns...]` | Save checkpoint for profile |
| `tarnished check <profile>` | Check if profile is tarnished |
| `tarnished status` | Show JSON status of all profiles |

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Clean (no changes) |
| 1 | Tarnished (changes detected) |
| 2 | Unknown profile |

## How It Works

**tarnished** is a simple CLI tool that tracks file state via checksums. It helps you know when code has changed and needs re-checking (linting, testing, etc.).

### Core Concepts

- **Profile:** A named set of glob patterns (e.g., `lint:php` tracks `app/**/*.php`)
- **Checkpoint:** A saved checksum representing file state at a specific moment
- **Tarnished:** A profile is "tarnished" if files have changed since the last checkpoint

### Implementation

tarnished uses file metadata (path + size + mtime) to compute checksums. This is:

- **Git-independent** - works regardless of commit history
- **Fast** - no file content hashing required
- **Simple** - single JSON files for config and state

### File Structure

```
.tarnished/
├── config.json    # Profile patterns (commit this)
└── state.json     # Current checksums (gitignored)
```

## Integration Example

Add to your CI/test scripts:

```bash
# After successful test run, save checkpoint
./run-tests.sh && tarnished save tests

# Before committing, check if tests need re-running
if ! tarnished check tests; then
    echo "Tests are tarnished - please run tests first"
    exit 1
fi
```

### Pre-commit Hook

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Check if any profiles are tarnished
status=$(tarnished status)
if echo "$status" | grep -q '"status": "tarnished"'; then
    echo "Some profiles are tarnished. Please run the relevant checks."
    tarnished status
    exit 1
fi
```

### CI Pipeline Example

```yaml
# In your CI workflow
- name: Check code state
  run: |
    tarnished check lint:php || echo "PHP files changed - running linter"
    tarnished check tests || echo "Test files changed - running tests"
```

## License

MIT