punt-kit 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.
- punt_kit-0.1.0/.beads/.gitignore +44 -0
- punt_kit-0.1.0/.beads/README.md +85 -0
- punt_kit-0.1.0/.beads/config.yaml +62 -0
- punt_kit-0.1.0/.beads/interactions.jsonl +0 -0
- punt_kit-0.1.0/.beads/issues.jsonl +41 -0
- punt_kit-0.1.0/.beads/metadata.json +4 -0
- punt_kit-0.1.0/.biff +5 -0
- punt_kit-0.1.0/.claude/settings.json +12 -0
- punt_kit-0.1.0/.claude-plugin/plugin.json +9 -0
- punt_kit-0.1.0/.gitattributes +3 -0
- punt_kit-0.1.0/.github/profile/README.md +27 -0
- punt_kit-0.1.0/.github/workflows/docs.yml +18 -0
- punt_kit-0.1.0/.github/workflows/lint.yml +23 -0
- punt_kit-0.1.0/.github/workflows/release.yml +93 -0
- punt_kit-0.1.0/.github/workflows/test.yml +20 -0
- punt_kit-0.1.0/.gitignore +19 -0
- punt_kit-0.1.0/.markdownlint-cli2.jsonc +3 -0
- punt_kit-0.1.0/.markdownlint.jsonc +10 -0
- punt_kit-0.1.0/AGENTS.md +101 -0
- punt_kit-0.1.0/CHANGELOG.md +16 -0
- punt_kit-0.1.0/CLAUDE.md +159 -0
- punt_kit-0.1.0/DESIGN.md +78 -0
- punt_kit-0.1.0/PKG-INFO +15 -0
- punt_kit-0.1.0/README.md +170 -0
- punt_kit-0.1.0/commands/audit-dev.md +26 -0
- punt_kit-0.1.0/commands/audit.md +25 -0
- punt_kit-0.1.0/commands/init-dev.md +39 -0
- punt_kit-0.1.0/commands/init.md +38 -0
- punt_kit-0.1.0/commands/reconcile-dev.md +28 -0
- punt_kit-0.1.0/commands/reconcile.md +157 -0
- punt_kit-0.1.0/patterns/copy-not-symlink.md +51 -0
- punt_kit-0.1.0/patterns/design-decision-log.md +73 -0
- punt_kit-0.1.0/patterns/doctor-checks.md +62 -0
- punt_kit-0.1.0/patterns/dual-command-path.md +51 -0
- punt_kit-0.1.0/patterns/dynamic-description-notify.md +57 -0
- punt_kit-0.1.0/patterns/prior-context-priming.md +59 -0
- punt_kit-0.1.0/patterns/sibling-ppid.md +77 -0
- punt_kit-0.1.0/patterns/stash-and-wrap.md +46 -0
- punt_kit-0.1.0/patterns/two-channel-display.md +56 -0
- punt_kit-0.1.0/patterns/two-phase-install.md +61 -0
- punt_kit-0.1.0/pyproject.toml +57 -0
- punt_kit-0.1.0/research/entire-io-hook-architecture.md +204 -0
- punt_kit-0.1.0/scoreboard.md +168 -0
- punt_kit-0.1.0/scripts/audit-all.sh +23 -0
- punt_kit-0.1.0/scripts/release-plugin.sh +46 -0
- punt_kit-0.1.0/scripts/restore-dev-plugin.sh +12 -0
- punt_kit-0.1.0/src/punt_kit/__init__.py +3 -0
- punt_kit-0.1.0/src/punt_kit/__main__.py +50 -0
- punt_kit-0.1.0/src/punt_kit/audit.py +650 -0
- punt_kit-0.1.0/src/punt_kit/detect.py +183 -0
- punt_kit-0.1.0/src/punt_kit/init.py +584 -0
- punt_kit-0.1.0/src/punt_kit/py.typed +0 -0
- punt_kit-0.1.0/src/punt_kit/templates/claude-md.md.j2 +24 -0
- punt_kit-0.1.0/src/punt_kit/templates/markdownlint-cli2.jsonc +3 -0
- punt_kit-0.1.0/src/punt_kit/templates/markdownlint.jsonc +10 -0
- punt_kit-0.1.0/src/punt_kit/templates/workflows/docs.yml +18 -0
- punt_kit-0.1.0/src/punt_kit/templates/workflows/lint-node.yml +19 -0
- punt_kit-0.1.0/src/punt_kit/templates/workflows/lint-python.yml +23 -0
- punt_kit-0.1.0/src/punt_kit/templates/workflows/release-python.yml.j2 +93 -0
- punt_kit-0.1.0/src/punt_kit/templates/workflows/test-python.yml +20 -0
- punt_kit-0.1.0/standards/cli.md +132 -0
- punt_kit-0.1.0/standards/distribution.md +284 -0
- punt_kit-0.1.0/standards/github.md +218 -0
- punt_kit-0.1.0/standards/naming.md +37 -0
- punt_kit-0.1.0/standards/node.md +117 -0
- punt_kit-0.1.0/standards/plugins.md +220 -0
- punt_kit-0.1.0/standards/python.md +287 -0
- punt_kit-0.1.0/standards/shell.md +121 -0
- punt_kit-0.1.0/standards/workflow.md +198 -0
- punt_kit-0.1.0/tests/__init__.py +0 -0
- punt_kit-0.1.0/tests/test_audit.py +339 -0
- punt_kit-0.1.0/tests/test_detect.py +121 -0
- punt_kit-0.1.0/tests/test_init.py +455 -0
- punt_kit-0.1.0/uv.lock +400 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# SQLite databases
|
|
2
|
+
*.db
|
|
3
|
+
*.db?*
|
|
4
|
+
*.db-journal
|
|
5
|
+
*.db-wal
|
|
6
|
+
*.db-shm
|
|
7
|
+
|
|
8
|
+
# Daemon runtime files
|
|
9
|
+
daemon.lock
|
|
10
|
+
daemon.log
|
|
11
|
+
daemon.pid
|
|
12
|
+
bd.sock
|
|
13
|
+
sync-state.json
|
|
14
|
+
last-touched
|
|
15
|
+
|
|
16
|
+
# Local version tracking (prevents upgrade notification spam after git ops)
|
|
17
|
+
.local_version
|
|
18
|
+
|
|
19
|
+
# Legacy database files
|
|
20
|
+
db.sqlite
|
|
21
|
+
bd.db
|
|
22
|
+
|
|
23
|
+
# Worktree redirect file (contains relative path to main repo's .beads/)
|
|
24
|
+
# Must not be committed as paths would be wrong in other clones
|
|
25
|
+
redirect
|
|
26
|
+
|
|
27
|
+
# Merge artifacts (temporary files from 3-way merge)
|
|
28
|
+
beads.base.jsonl
|
|
29
|
+
beads.base.meta.json
|
|
30
|
+
beads.left.jsonl
|
|
31
|
+
beads.left.meta.json
|
|
32
|
+
beads.right.jsonl
|
|
33
|
+
beads.right.meta.json
|
|
34
|
+
|
|
35
|
+
# Sync state (local-only, per-machine)
|
|
36
|
+
# These files are machine-specific and should not be shared across clones
|
|
37
|
+
.sync.lock
|
|
38
|
+
sync_base.jsonl
|
|
39
|
+
|
|
40
|
+
# NOTE: Do NOT add negation patterns (e.g., !issues.jsonl) here.
|
|
41
|
+
# They would override fork protection in .git/info/exclude, allowing
|
|
42
|
+
# contributors to accidentally commit upstream issue databases.
|
|
43
|
+
# The JSONL files (issues.jsonl, interactions.jsonl) and config files
|
|
44
|
+
# are tracked by git by default since no pattern above ignores them.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Beads - AI-Native Issue Tracking
|
|
2
|
+
|
|
3
|
+
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
|
|
4
|
+
|
|
5
|
+
## What is Beads?
|
|
6
|
+
|
|
7
|
+
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
|
|
8
|
+
|
|
9
|
+
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Essential Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Create new issues
|
|
17
|
+
bd create "Add user authentication"
|
|
18
|
+
|
|
19
|
+
# View all issues
|
|
20
|
+
bd list
|
|
21
|
+
|
|
22
|
+
# View issue details
|
|
23
|
+
bd show <issue-id>
|
|
24
|
+
|
|
25
|
+
# Update issue status
|
|
26
|
+
bd update <issue-id> --status in_progress
|
|
27
|
+
bd update <issue-id> --status done
|
|
28
|
+
|
|
29
|
+
# Sync with git remote
|
|
30
|
+
bd sync
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Working with Issues
|
|
34
|
+
|
|
35
|
+
Issues in Beads are:
|
|
36
|
+
|
|
37
|
+
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
|
|
38
|
+
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
|
|
39
|
+
- **Branch-aware**: Issues can follow your branch workflow
|
|
40
|
+
- **Always in sync**: Auto-syncs with your commits
|
|
41
|
+
|
|
42
|
+
## Why Beads?
|
|
43
|
+
|
|
44
|
+
✨ **AI-Native Design**
|
|
45
|
+
|
|
46
|
+
- Built specifically for AI-assisted development workflows
|
|
47
|
+
- CLI-first interface works seamlessly with AI coding agents
|
|
48
|
+
- No context switching to web UIs
|
|
49
|
+
|
|
50
|
+
🚀 **Developer Focused**
|
|
51
|
+
|
|
52
|
+
- Issues live in your repo, right next to your code
|
|
53
|
+
- Works offline, syncs when you push
|
|
54
|
+
- Fast, lightweight, and stays out of your way
|
|
55
|
+
|
|
56
|
+
🔧 **Git Integration**
|
|
57
|
+
|
|
58
|
+
- Automatic sync with git commits
|
|
59
|
+
- Branch-aware issue tracking
|
|
60
|
+
- Intelligent JSONL merge resolution
|
|
61
|
+
|
|
62
|
+
## Get Started with Beads
|
|
63
|
+
|
|
64
|
+
Try Beads in your own projects:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Install Beads
|
|
68
|
+
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
|
69
|
+
|
|
70
|
+
# Initialize in your repo
|
|
71
|
+
bd init
|
|
72
|
+
|
|
73
|
+
# Create your first issue
|
|
74
|
+
bd create "Try out Beads"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Learn More
|
|
78
|
+
|
|
79
|
+
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
|
|
80
|
+
- **Quick Start Guide**: Run `bd quickstart`
|
|
81
|
+
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
*Beads: Issue tracking that moves at the speed of thought* ⚡
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Beads Configuration File
|
|
2
|
+
# This file configures default behavior for all bd commands in this repository
|
|
3
|
+
# All settings can also be set via environment variables (BD_* prefix)
|
|
4
|
+
# or overridden with command-line flags
|
|
5
|
+
|
|
6
|
+
# Issue prefix for this repository (used by bd init)
|
|
7
|
+
# If not set, bd init will auto-detect from directory name
|
|
8
|
+
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
|
|
9
|
+
# issue-prefix: ""
|
|
10
|
+
|
|
11
|
+
# Use no-db mode: load from JSONL, no SQLite, write back after each command
|
|
12
|
+
# When true, bd will use .beads/issues.jsonl as the source of truth
|
|
13
|
+
# instead of SQLite database
|
|
14
|
+
# no-db: false
|
|
15
|
+
|
|
16
|
+
# Disable daemon for RPC communication (forces direct database access)
|
|
17
|
+
# no-daemon: false
|
|
18
|
+
|
|
19
|
+
# Disable auto-flush of database to JSONL after mutations
|
|
20
|
+
# no-auto-flush: false
|
|
21
|
+
|
|
22
|
+
# Disable auto-import from JSONL when it's newer than database
|
|
23
|
+
# no-auto-import: false
|
|
24
|
+
|
|
25
|
+
# Enable JSON output by default
|
|
26
|
+
# json: false
|
|
27
|
+
|
|
28
|
+
# Default actor for audit trails (overridden by BD_ACTOR or --actor)
|
|
29
|
+
# actor: ""
|
|
30
|
+
|
|
31
|
+
# Path to database (overridden by BEADS_DB or --db)
|
|
32
|
+
# db: ""
|
|
33
|
+
|
|
34
|
+
# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON)
|
|
35
|
+
# auto-start-daemon: true
|
|
36
|
+
|
|
37
|
+
# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE)
|
|
38
|
+
# flush-debounce: "5s"
|
|
39
|
+
|
|
40
|
+
# Git branch for beads commits (bd sync will commit to this branch)
|
|
41
|
+
# IMPORTANT: Set this for team projects so all clones use the same sync branch.
|
|
42
|
+
# This setting persists across clones (unlike database config which is gitignored).
|
|
43
|
+
# Can also use BEADS_SYNC_BRANCH env var for local override.
|
|
44
|
+
# If not set, bd sync will require you to run 'bd config set sync.branch <branch>'.
|
|
45
|
+
# sync-branch: "beads-sync"
|
|
46
|
+
|
|
47
|
+
# Multi-repo configuration (experimental - bd-307)
|
|
48
|
+
# Allows hydrating from multiple repositories and routing writes to the correct JSONL
|
|
49
|
+
# repos:
|
|
50
|
+
# primary: "." # Primary repo (where this database lives)
|
|
51
|
+
# additional: # Additional repos to hydrate from (read-only)
|
|
52
|
+
# - ~/beads-planning # Personal planning repo
|
|
53
|
+
# - ~/work-planning # Work planning repo
|
|
54
|
+
|
|
55
|
+
# Integration settings (access with 'bd config get/set')
|
|
56
|
+
# These are stored in the database, not in this file:
|
|
57
|
+
# - jira.url
|
|
58
|
+
# - jira.project
|
|
59
|
+
# - linear.url
|
|
60
|
+
# - linear.api-key
|
|
61
|
+
# - github.org
|
|
62
|
+
# - github.repo
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{"id":"punt-kit-0a3","title":"punt init: handle upgrade of existing projects (scaffold vs. upgrade)","description":"punt init: handle upgrade of existing projects (scaffold vs. upgrade)\n\nDECISION: Approach E — Hybrid.\n\nDeterministic layer handles mechanical files where the template IS the standard (no valid reason to diverge):\n- .markdownlint.jsonc, .markdownlint-cli2.jsonc\n- .github/workflows/docs.yml\n- py.typed\n- .gitignore entries\n\nLLM layer handles files where project context matters (valid customizations exist):\n- .github/workflows/lint.yml, test.yml, release.yml (different deps, extras, timeout values)\n- CLAUDE.md (project-specific overrides, escalation notes)\n- pyproject.toml tool sections (project-specific ruff/mypy/pyright config)\n\nJinja2 templates (punt-kit-k79) are still needed for the deterministic layer — release.yml needs package name substitution, docs.yml is static but other templates may need variables.\n\nThe LLM layer would be a Claude Code skill or agent (punt audit --fix) that reads current standards docs, audits the project, and makes contextual decisions about what to fix. This is a separate bead.\n\nIMPLEMENTATION PLAN:\n1. punt-kit-k79: Jinja2 template substitution for deterministic layer\n2. New bead: punt audit command — deterministic file creation/update\n3. New bead: punt audit --fix or /punt-kit:audit skill — LLM-based standards audit","status":"closed","priority":3,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-20T08:12:55.626734-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:28:04.781215-08:00","closed_at":"2026-02-20T09:28:04.781215-08:00","close_reason":"Design decision made: Approach E (hybrid). Deterministic layer → punt-kit-2qf. LLM layer → punt-kit-2l0. Jinja2 templates → punt-kit-k79 (existing)."}
|
|
2
|
+
{"id":"punt-kit-0q2","title":"Enable GitHub Copilot code review across punt-labs org","description":"Enable Copilot code review in org settings. Configure automatic review on all repos. Add copilot-review-instructions.md to repos with custom review focus areas. Requires Copilot Business or Enterprise.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:27.949446-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T14:45:13.492834-08:00","closed_at":"2026-02-19T14:45:13.492834-08:00","close_reason":"Copilot code review enabled on all 11 repos (review_on_push=true in rulesets)"}
|
|
3
|
+
{"id":"punt-kit-18i","title":"Add install.sh to langlearn projects","description":"langlearn, langlearn-anki, langlearn-imagegen (and possibly langlearn-types) need POSIX sh install scripts per distribution.md. Use git URL workaround pattern from biff/quarry/langlearn-tts.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:54:19.995055-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.811521-08:00","closed_at":"2026-02-22T07:32:54.811521-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
|
4
|
+
{"id":"punt-kit-1cg","title":"Enable Dependabot alerts, security updates, secret scanning, and push protection across org","description":"Enable for all repos: Dependabot alerts, Dependabot security updates, secret scanning, push protection. These are org-level security settings per github.md standard.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:29.835346-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T14:45:13.349735-08:00","closed_at":"2026-02-19T14:45:13.349735-08:00","close_reason":"Dependabot security updates, secret scanning, and push protection enabled on all 11 repos"}
|
|
5
|
+
{"id":"punt-kit-1ox","title":"Standard: pre-commit hook should run lint and format checks","description":"Claude Code sessions routinely skip the format check before committing, causing predictable CI failures. The quality gates command is documented in CLAUDE.md but not enforced mechanically.\n\nProposal: add ruff check and ruff format --check to the standard pre-commit hook alongside the existing beads flush. This makes lint/format failures impossible to commit, regardless of whether the agent or human remembers to run the full pipeline.\n\nThe hook should be fast (ruff is sub-second on our codebases) and should not include slow checks like mypy/pyright/pytest — those belong in CI. The goal is to catch the trivially preventable failures (formatting, import sorting, unused variables) at commit time.\n\nAffected projects: all Python projects in the monorepo that use ruff. The hook template would live in punt-kit/standards/ and be referenced from python.md.","status":"open","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-23T22:59:41.816768-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-23T22:59:41.816768-08:00"}
|
|
6
|
+
{"id":"punt-kit-2l0","title":"punt audit --llm: AI-powered standards audit skill","description":"Claude Code skill or agent that reads current punt-kit standards, audits a project, and makes contextual decisions about what to fix. The LLM layer of approach E (punt-kit-0a3).\n\nThis handles files where project-specific context matters:\n- Workflow files (lint.yml, test.yml, release.yml) — understands that --all-extras is intentional\n- CLAUDE.md — knows what sections should exist, can add missing ones without clobbering\n- pyproject.toml tool config — can distinguish intentional overrides from drift\n\nCould be implemented as:\n- A /punt-kit:audit skill in the punt-kit Claude Code plugin (punt-kit-6iy)\n- A standalone agent invoked by punt audit --llm\n- Part of the feature-dev workflow\n\nDepends on: punt audit deterministic layer (for the report of what needs judgment)\nParent design: punt-kit-0a3 (approach E).","status":"closed","priority":4,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-20T09:27:58.886144-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T10:14:41.123082-08:00","closed_at":"2026-02-20T10:14:41.123082-08:00","close_reason":"Implemented as /punt reconcile command in Claude Code plugin. punt init is now create-only; reconciliation lives in the LLM layer. PR #9.","dependencies":[{"issue_id":"punt-kit-2l0","depends_on_id":"punt-kit-2qf","type":"blocks","created_at":"2026-02-20T09:28:04.653352-08:00","created_by":"\"jmf-pobox\""}]}
|
|
7
|
+
{"id":"punt-kit-2qf","title":"punt audit: deterministic standards compliance check and fix","description":"Add a punt audit command that checks an existing project against current standards and fixes mechanical gaps.\n\nDETERMINISTIC SCOPE (safe to auto-fix):\n- Missing .markdownlint.jsonc → create from template\n- Missing .markdownlint-cli2.jsonc → create from template\n- Missing .github/workflows/docs.yml → create from template\n- Missing py.typed → create\n- Missing .gitignore entries → append\n- Missing CHANGELOG.md → create skeleton\n- Missing pyproject.toml sections (urls, build-system) → add if absent\n\nREPORT-ONLY (not auto-fixed, flagged for LLM layer):\n- Workflow files that differ from templates (lint.yml, test.yml, release.yml)\n- CLAUDE.md gaps (missing escalation note, missing standards references)\n- pyproject.toml tool config drift\n\nOUTPUT:\n- punt audit → report what's missing/drifted (exit 0 if clean, exit 1 if issues)\n- punt audit --fix → create missing mechanical files, report judgment items\n\nDepends on punt-kit-k79 (Jinja2 templates) for release.yml substitution.\nParent design: punt-kit-0a3 (approach E).","status":"closed","priority":3,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-20T09:27:58.752615-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:47:16.528705-08:00","closed_at":"2026-02-20T09:47:16.528705-08:00","close_reason":"Implemented --fix flag with markdownlint, py.typed, CHANGELOG checks. PR #8 merged.","dependencies":[{"issue_id":"punt-kit-2qf","depends_on_id":"punt-kit-k79","type":"blocks","created_at":"2026-02-20T09:28:04.532996-08:00","created_by":"\"jmf-pobox\""}]}
|
|
8
|
+
{"id":"punt-kit-3ax","title":"Enable auto-delete head branches across all repos","description":"Enable auto-delete head branches in repo settings for all punt-labs repos. Cleans up merged PR branches automatically.","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:31.091226-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T15:44:36.911751-08:00","closed_at":"2026-02-19T15:44:36.911751-08:00","close_reason":"Auto-delete head branches enabled on all 11 repos"}
|
|
9
|
+
{"id":"punt-kit-3vr","title":"Automated TestPyPI + PyPI release workflow with trusted publishing","description":"Automated release pipeline for all Python repos. BLOCKED: waiting for punt-labs community org approval on pypi.org and test.pypi.org (requested 2026-02-20). Once approved, configure trusted publishers and roll out release.yml.","status":"open","priority":3,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-20T06:48:21.419625-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T13:04:09.906115-08:00"}
|
|
10
|
+
{"id":"punt-kit-4ob","title":"Pin action SHAs consistently across langlearn CI","description":"langlearn-anki pins astral-sh/setup-uv to v5.4.2 while the other three langlearn projects pin to v7.3.0. All should use the same version.","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:54:23.016892-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.815201-08:00","closed_at":"2026-02-22T07:32:54.815201-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
|
11
|
+
{"id":"punt-kit-64b","title":"Standard: --json global flag for CLI output","description":"All CLI tools should support a --json global flag for machine-readable output. This is a cross-cutting CLI standard that applies to biff, quarry, langlearn-tts, and future CLI projects.\n\n## What\nAdd --json as a global typer option that switches all output to JSON. When enabled, commands emit structured JSON to stdout instead of human-formatted rich output. Errors also emit JSON to stderr.\n\n## Why\nProgrammatic consumers (scripts, CI, other tools) need structured output. The current human-formatted output is unparseable. Every project has independently identified this need (biff-n68, quarry-imv, lltts-hx3).\n\n## Standard definition needed\n- Global flag: --json (typer callback or app-level option)\n- Output contract: JSON to stdout, one object per command invocation\n- Error contract: JSON to stderr with error field\n- Document in standards/cli.md\n\n## Adoption tracking (project beads)\n- biff-n68: Add --json global flag to CLI\n- quarry-imv: Add --json global flag to CLI\n- lltts-hx3: Add --json global flag to CLI","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-20T09:03:44.903044-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:24:10.797534-08:00","closed_at":"2026-02-20T09:24:10.797534-08:00","close_reason":"Standard already defined in standards/cli.md (Machine-Readable Output section). Adoption tracked by project beads: biff-n68, quarry-imv, lltts-hx3."}
|
|
12
|
+
{"id":"punt-kit-6eb","title":"Migrate prfaq to marketplace","description":"Added prfaq to claude-plugins marketplace catalog. Rewrote install.sh from 481-line bash to 85-line POSIX sh.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:22.615739-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:27.006379-08:00","closed_at":"2026-02-21T14:57:27.006379-08:00","close_reason":"Completed in standards sweep session"}
|
|
13
|
+
{"id":"punt-kit-6iy","title":"Explore punt-kit Claude Code plugin for AI-enhanced standards review","description":"punt-kit CLI handles deterministic scaffolding and compliance checks. A separate plugin layer (punt-kit-claude) could add AI-enhanced analysis: reviewing workflow content against standards, assessing CLAUDE.md quality, flagging code pattern violations, evaluating test meaningfulness. Would follow the Biff pattern (CLI + plugin duality) but the plugin side would be genuinely AI-driven — a standards advisor agent, not just slash command wrappers around deterministic checks. Separate concern from the CLI: deterministic checks stay in punt-kit, semantic analysis lives in the plugin.","status":"closed","priority":4,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-17T12:25:18.106027-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T10:14:41.210263-08:00","closed_at":"2026-02-20T10:14:41.210263-08:00","close_reason":"Satisfied by the punt-kit Claude Code plugin (.claude-plugin/ + commands/reconcile.md). PR #9."}
|
|
14
|
+
{"id":"punt-kit-6q9","title":"Add branch protection rulesets to all repos","description":"Add branch protection ruleset to main on every punt-labs repo: require PR with 1 approval, require status checks to pass, prevent force push, prevent branch deletion. Currently only prfaq has a ruleset (weak: 0 approvals, no status checks). Repos: punt-kit, biff, dungeon, prfaq (fix), koch-trainer-swift, feature-forge, .github, and any newly published repos.","status":"closed","priority":1,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:36.808012-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T14:34:58.619832-08:00","closed_at":"2026-02-19T14:34:58.619832-08:00","close_reason":"Branch protection rulesets with required status checks applied to all 11 repos"}
|
|
15
|
+
{"id":"punt-kit-86e","title":"Update distribution/plugin standards with marketplace installation lessons","description":"## Context\n\nThe biff marketplace migration (Feb 2026) proved that several assumptions in\ndistribution.md and plugins.md are wrong or outdated. The dungeon and biff\nmigrations surfaced hard-won lessons about how Claude Code plugins actually\nwork in production that need to be captured as updated standards.\n\n## What's Wrong in Current Standards\n\n### distribution.md — Largely obsolete for plugins\n\nThe current standard says plugin projects need `curl | bash` installers that\nclone repos to `~/.claude/plugins/local-plugins/plugins/\u003cname\u003e`. This is the\nOLD model. The marketplace replaces it entirely:\n\n- **Old**: `curl | bash` → clone → register in local marketplace → clear cache\n- **New**: `biff install` → register punt-labs marketplace → `claude plugin install`\n\nThe `install.sh` pattern should be removed for marketplace plugins. The \"MCP\nserver projects\" section still applies to projects that are ONLY MCP servers\n(like quarry), but hybrid plugin+MCP projects (biff) use a different path.\n\n### plugins.md — MCP server declaration is ambiguous\n\nThe current standard says MCP servers use `.mcp.json` at plugin root. This is\n*a* mechanism, but it has a critical gotcha: Claude Code loads `.mcp.json` from\nthe plugin's cached directory, which means ANY `.mcp.json` committed to the repo\nbecomes an MCP server under that plugin — even if it was meant for local dev use.\n\nThe biff migration hit this: a `.mcp.json` defining `claude-flow` (from a\nprevious experiment) was committed to the biff repo. When installed via\nmarketplace, `plugin:biff:claude-flow` appeared as a ghost MCP server.\n\n**Correct guidance**: Declare MCP servers in `plugin.json` mcpServers (explicit,\nversion-controlled). Gitignore `.mcp.json` (project-local, not part of plugin\ndistribution).\n\n## Lessons Learned (Proven Through biff + dungeon Migrations)\n\n### 1. Marketplace cache = full git clone\n\nEverything in the repo gets cached, not just plugin components. This means:\n- `.mcp.json` → becomes an MCP server\n- `.claude-flow/` → could interfere with other plugins\n- `node_modules/` → NOT cached (gitignored), so npm deps need SessionStart hook\n- Solution: gitignore everything that's not part of the plugin distribution\n\n### 2. Two-step install for CLI+plugin hybrids\n\nProjects like biff have TWO artifacts: a CLI (`pip install`) and a plugin\n(marketplace). The CLI must be installed BEFORE the plugin because the MCP\nserver config references `biff serve --transport stdio`.\n\n```bash\nuv tool install punt-biff # Step 1: CLI on PATH\nbiff install # Step 2: marketplace + plugin\n```\n\nThis is different from pure plugins (dungeon) where the plugin IS the project.\n\n### 3. `uv tool install` resolves fresh, `uv sync` respects lockfile\n\nIf pyproject.toml says `fastmcp\u003e=2.0.0` and the lockfile pins 2.14.5, then\n`uv sync` keeps 2.14.5 but `uv tool install` resolves fresh and gets 3.0.1.\nThis caused a production crash (FastMCP 3.x removed internal `_tool_manager`\nAPI).\n\n**Rule**: Pin major versions in dependencies for CLI tools that end users\ninstall via `uv tool install`. The lockfile protects dev, not production.\n\n### 4. Stale local plugin directories persist as orphans\n\nAfter marketplace migration, `~/.claude/plugins/\u003cname\u003e/` from the old local\ninstall remains. Claude Code creates `.orphaned_at` but the directory persists.\nThree cleanup locations:\n- `~/.claude/plugins/\u003cname\u003e/` (orphaned local plugin)\n- `~/.claude/plugins/cache/local/\u003cname\u003e/` (old cache)\n- `installed_plugins.json` entries with old scope\n\n`biff uninstall` must clean all three. New projects should never create local\nplugins.\n\n### 5. SessionStart hook timing and restart penalty\n\nSessionStart deploys commands to `~/.claude/commands/` BEFORE Claude loads\ncommands. But on first install, the hook hasn't run yet. So:\n- Install → restart 1 → hook runs, deploys commands → restart 2 → commands work\n\nThis is a UX cost. The dungeon migration documented \"restart twice\". Biff\naccepts the same penalty. No workaround exists in the current plugin system.\n\n### 6. Permission auto-allow via jq in SessionStart\n\nMCP tool permissions (e.g., `mcp__plugin_biff_biff__*`) must be added to\n`~/.claude/settings.json` `permissions.allow`. The SessionStart hook does this\nidempotently with jq. Without this, users get permission prompts on every tool\ncall.\n\n### 7. MCP tool naming is deterministic\n\n`mcp__plugin_{plugin}_{server}__{tool}` — where {plugin} is the plugin name and\n{server} is the mcpServers key. If the plugin name and server name are the same\n(biff/biff), you get `mcp__plugin_biff_biff__*`. This is different from\nuser-registered MCP servers (`mcp__{server}__{tool}`).\n\n### 8. Plugin author should be org, not person\n\nUse `\"name\": \"Punt Labs\"` in plugin.json author, not a personal name. This\naffects marketplace catalog display and establishes org identity.\n\n### 9. Marketplace uninstall has blind spots\n\n`claude plugin uninstall` doesn't clean everything:\n- Deployed commands in `~/.claude/commands/`\n- Permission entries in settings.json\n- Statusline wrapping\n- Old local plugin directories\n\nThe project's `uninstall` command must handle all of these explicitly.\n\n## What Needs to Change\n\n1. **distribution.md**: Replace `curl | bash` plugin install path with\n marketplace install. Add two-step install pattern for CLI+plugin hybrids.\n Add `uv tool install` pinning guidance.\n\n2. **plugins.md**: Add `.mcp.json` vs `plugin.json` mcpServers guidance.\n Add gitignore checklist for plugin repos. Add SessionStart hook pattern\n as required (not just output suppression). Update author field guidance.\n\n3. **New**: Consider a migration guide for existing users of local-installed\n plugins (dungeon, prfaq, feature-forge, z-spec).","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T10:49:14.578542-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T11:07:53.804861-08:00","closed_at":"2026-02-21T11:07:53.804861-08:00","close_reason":"Standards updated in PR #13. distribution.md rewritten for marketplace. plugins.md rewritten with MCP declaration, required hooks, gitignore checklist, tool naming."}
|
|
16
|
+
{"id":"punt-kit-88c","title":"Plugin dev/prod isolation: dual-namespace standard for Claude Code plugin authors","description":"## Problem\n\nClaude Code plugin authors face a recurring conflict: marketplace installs (for consumers) collide with local development (for developers). This affects all punt-labs plugins (punt, dungeon, biff, prfaq) and any third-party plugin author.\n\n## Solution: --plugin-dir + Namespaced Plugin Name\n\n### Core Mechanism\n\n- Working tree `plugin.json` uses `{name}-dev` (e.g., `punt-dev`)\n- Marketplace uses `{name}` (e.g., `punt`)\n- Developers launch with `claude --plugin-dir .` — loads local plugin alongside marketplace\n- Both plugins visible simultaneously: `/punt:*` (marketplace) + `/punt-dev:*` (local)\n\nCWD auto-discovery is unreliable (tested 2026-02-22). `--plugin-dir` is the documented, supported mechanism — session-only, no installation needed.\n\n### Namespace Scope\n\nPlugin name prefixes everything: commands, MCP tools, skills, agents, hooks.\n\n| Layer | Production | Development |\n|-------|-----------|-------------|\n| Commands | `/punt init` | `/punt-dev init-dev` |\n| MCP tools | `mcp__plugin_punt_*` | `mcp__plugin_punt_dev_*` |\n| Skills | `punt:reconcile` | `punt-dev:reconcile-dev` |\n\n### Dev Commands\n\nEach prod command has a `-dev` variant that runs via `uv run --directory ${CLAUDE_PLUGIN_ROOT}` against the working tree code, bypassing the installed CLI.\n\n### Release Flow\n\n1. `scripts/release-plugin.sh`: swaps plugin name to prod, removes -dev commands\n2. Tag the release commit\n3. `scripts/restore-dev-plugin.sh`: restores dev name and commands on main\n4. Marketplace cache clones from tag — consumers see only prod artifacts\n\n### Audit Enforcement\n\n`punt audit` checks every prod command has a corresponding `-dev` variant.\n\n## Tested Unknowns\n\n| # | Question | Answer |\n|---|----------|--------|\n| 1 | Hyphen in plugin name → MCP prefix | Hyphens → underscores (`biff-dev` → `mcp__plugin_biff_dev_tty__*`) |\n| 2 | Hook matchers: regex or glob? | Full regex (`biff(_dev)?` works) |\n| 3 | Extra JSON in .claude-plugin/ | Ignored (only `plugin.json` loaded) |\n| 4 | CWD auto-discovery reliable? | **No.** Does not load local plugins when marketplace plugin exists. |\n| 5 | `--plugin-dir .` coexists with marketplace? | **Yes.** Both load simultaneously with different names. |\n\n## Status\n\n- [x] Architecture designed\n- [x] Test unknowns resolved\n- [x] Implement for punt-kit (PR #15)\n- [ ] Propagate to biff, dungeon, prfaq","status":"closed","priority":2,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-22T09:34:45.607281-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T11:17:13.646276-08:00","closed_at":"2026-02-22T11:17:13.646276-08:00","close_reason":"Merged PR #15. Dev/prod isolation via --plugin-dir + punt-dev name. Propagation to biff/dungeon/prfaq is separate work."}
|
|
17
|
+
{"id":"punt-kit-8wd","title":"Add release.yml to langlearn projects","description":"langlearn, langlearn-anki, langlearn-imagegen, langlearn-types all missing release.yml. Use punt-kit template. Blocked on PyPI org prefix approval for actual publishing but the workflow should be in place.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:54:18.605204-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.809588-08:00","closed_at":"2026-02-22T07:32:54.809588-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
|
18
|
+
{"id":"punt-kit-b8l","title":"Automated TestPyPI + PyPI release workflow","status":"closed","priority":1,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-19T18:16:02.316309-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T21:14:55.117257-08:00","closed_at":"2026-02-19T21:14:55.117257-08:00","close_reason":"All 4 PRs merged: punt-kit#3, biff#43, quarry#51, langlearn-tts#22. Release workflows with OIDC trusted publishing and TestPyPI gate deployed to all Python repos."}
|
|
19
|
+
{"id":"punt-kit-bjb","title":"Standard: PostToolUse output suppression hook for MCP plugins","description":"MCP server plugins in Claude Code should include a PostToolUse hook that suppresses verbose tool output from cluttering the conversation. This is a cross-cutting plugin integration pattern.\n\n## What\nA PostToolUse hook that intercepts MCP tool results and provides a concise summary instead of raw output. Prevents large search results, document contents, or verbose responses from consuming context window.\n\n## Why\nMCP tools often return large payloads (search results, document chunks, metadata). Without suppression, these dominate the conversation context. Both quarry and langlearn-tts have independently identified this need (quarry-uc2, lltts-5zg).\n\n## Standard definition needed\n- Hook type: PostToolUse prompt-based hook\n- Pattern: match on tool name prefix, summarize output\n- Document in standards/plugins.md\n\n## Adoption tracking (project beads)\n- quarry-uc2: Add PostToolUse output suppression hook\n- lltts-5zg: Add PostToolUse output suppression hook","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-20T09:03:50.121995-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:24:10.877183-08:00","closed_at":"2026-02-20T09:24:10.877183-08:00","close_reason":"Standard already defined in standards/plugins.md (Output Suppression section). Adoption tracked by project beads: quarry-uc2, lltts-5zg."}
|
|
20
|
+
{"id":"punt-kit-d58","title":"Org-wide .biff rollout (non-langlearn)","description":"Added .biff to punt-kit, quarry, langlearn-tts, quarry-menubar, koch-trainer-swift, prfaq, dungeon, feature-forge, z-spec, .github, claude-plugins. All committed and pushed.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:08.984925-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:13.314426-08:00","closed_at":"2026-02-21T14:57:13.314426-08:00","close_reason":"Completed in standards sweep session"}
|
|
21
|
+
{"id":"punt-kit-dn4","title":"Add docs CI (markdownlint) to all repos missing it","description":"5 repos lack docs.yml workflow: biff, quarry, langlearn-tts, koch-trainer-swift, quarry-menubar.\n\nDecisions:\n- Exclude dot directories from linting: .claude/, .beads/, .venv/\n- Exclude build artifacts: DerivedData/ (quarry-menubar)\n- MD013: false (line length, org standard)\n- MD060: false (table column style, org standard)\n- MD024: false only in CHANGELOG.md files (duplicate headings are inherent to Keep a Changelog format). Use per-file markdownlint-disable comment, not global disable.\n- MD033: allowed_elements=[img, p] (README layouts need width/align attributes)\n- MD041: false for biff (plugin command files use frontmatter before h2)\n- MD025: false for quarry (test fixtures have multiple h1)\n- MD040: FIX (add language specifiers to fenced code blocks — real quality issue)\n- MD032/MD022/MD031: FIX (blanks around lists/headings/fences — formatting)\n\nSteps:\n1. Create org-standard .markdownlint.jsonc template in punt-kit\n2. Add .markdownlint-cli2.jsonc with ignorePatterns per repo\n3. Fix remaining lint errors in each repo\n4. Add docs.yml workflow (same as punt-kit template)\n5. Update rulesets to require docs check\n6. One PR per repo","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-19T21:38:22.918925-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T22:20:26.534633-08:00","closed_at":"2026-02-19T22:20:26.534633-08:00","close_reason":"Added docs CI (markdownlint) to all 5 repos: biff#44, quarry#52, langlearn-tts#23, koch-trainer-swift#81, quarry-menubar#20. All merged. Updated rulesets to require docs check."}
|
|
22
|
+
{"id":"punt-kit-eex","title":"Transfer repos to punt-labs org: quarry, langlearn-tts, z-spec, quarry-menubar","description":"Transfer existing repos from jmf-pobox to punt-labs org. Use GitHub transfer (Settings \u003e Danger Zone \u003e Transfer) or the API (POST /repos/{owner}/{repo}/transfer). Repos to transfer:\n- jmf-pobox/quarry-mcp → punt-labs/quarry (rename during transfer)\n- jmf-pobox/langlearn-tts → punt-labs/langlearn-tts\n- jmf-pobox/claude-z-spec-plugin → punt-labs/z-spec (rename during transfer)\n- jmf-pobox/quarry-menubar → punt-labs/quarry-menubar\n\nAfter transfer: update git remotes in local clones, update cross-references in README and PROJECTS links, reconfigure any webhooks or deploy keys.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:33.601696-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-18T07:06:34.614694-08:00","closed_at":"2026-02-18T07:06:34.614694-08:00","close_reason":"All four repos transferred to punt-labs org (quarry, langlearn-tts, z-spec, quarry-menubar). URLs updated across all projects. Git remotes updated locally."}
|
|
23
|
+
{"id":"punt-kit-ep7","title":"Add top-level permissions: {} to release workflows","description":"Defense-in-depth: add workflow-level permissions: {} to all release.yml files so jobs only get explicitly granted permissions. Requires adding contents: read to the build job (for actions/checkout). Applies to all 4 Python repos (punt-kit, biff, quarry, langlearn-tts) and the release-python.yml template.","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-19T21:10:17.216766-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:09:17.48862-08:00","closed_at":"2026-02-20T09:09:17.48862-08:00","close_reason":"Rolled out across all 4 Python repos (punt-kit, biff, quarry, langlearn-tts). PRs: punt-kit#5, biff#47, quarry#55, langlearn-tts#26 — all merged."}
|
|
24
|
+
{"id":"punt-kit-fbq","title":"Rename PyPI packages to punt- prefix","description":"Rename all PyPI packages to use punt- org prefix for consistency:\n- quarry-mcp → punt-quarry\n- biff-mcp → punt-biff (never published, just rename in pyproject.toml)\n- langlearn-tts → punt-langlearn-tts\n- punt-kit already correct\n\nFor published packages (quarry-mcp, langlearn-tts): publish final version under old name that prints deprecation warning and depends on new name. Then publish under new name.\n\nUpdate install docs, README badges, .mcpb manifests, CLI entry points, and import names (if applicable) in each project.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-18T07:16:18.380113-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T16:12:24.393653-08:00","closed_at":"2026-02-19T16:12:24.393653-08:00","close_reason":"All 3 PyPI packages renamed: biff-mcp→punt-biff (PR#42), quarry-mcp→punt-quarry (PR#50), langlearn-tts→punt-langlearn-tts (PR#21). All merged."}
|
|
25
|
+
{"id":"punt-kit-g4l","title":"Add pyright config to quarry pyproject.toml","description":"quarry was the only Python project missing [tool.pyright]. Added strict mode, Python 3.13.","status":"closed","priority":1,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:36.482518-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:39.851454-08:00","closed_at":"2026-02-21T14:57:39.851454-08:00","close_reason":"Completed in standards sweep session"}
|
|
26
|
+
{"id":"punt-kit-h11","title":"Add CI workflows to repos missing them","description":"Add GitHub Actions CI per project type (per github.md standards).\n\nAlready have CI:\n- punt-kit (lint, test, docs, release)\n- biff (lint, test, hosted-nats)\n- quarry (lint, test)\n- langlearn-tts (ci)\n- koch-trainer-swift (ci)\n\nNeed CI:\n- quarry-menubar: build + test + lint (Swift macOS)\n- prfaq: markdown lint + link validation (plugin/prompts)\n- dungeon: markdown lint + link validation (plugin/prompts)\n- feature-forge: markdown lint + link validation (plugin/prompts)\n- z-spec: markdown lint + link validation (plugin/prompts)\n- .github: markdown lint + link validation (docs)","status":"closed","priority":1,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:39.868505-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T12:56:01.414096-08:00","closed_at":"2026-02-19T12:56:01.414096-08:00","close_reason":"All 6 CI workflows created, pushed, and passing. PRs: quarry-menubar#19, prfaq#16, dungeon#1, feature-forge#1, z-spec#2, .github#1"}
|
|
27
|
+
{"id":"punt-kit-k79","title":"punt init: add Jinja2 substitution for workflow templates","description":"_init_workflows() in init.py copies workflow templates verbatim (read_text/write_text) with no substitution. The release-python.yml template has PACKAGE_NAME and CLI_COMMAND placeholders that should be replaced with actual values derived from pyproject.toml (project name, CLI entry points). Other templates like claude-md.md.j2 already use Jinja2 rendering. Convert workflow templates to .j2 format and render them with project-specific values during punt init.","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-19T21:05:23.848369-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:37:31.798844-08:00","closed_at":"2026-02-20T09:37:31.798844-08:00","close_reason":"Implemented in PR #7. Release template now uses Jinja2 with {{ package_name }} and {{ cli_command }} extracted from pyproject.toml. Gracefully skips when metadata is incomplete."}
|
|
28
|
+
{"id":"punt-kit-nz7","title":"Configure required status checks on repos with CI","description":"After CI workflows exist, configure required status checks in branch protection so CI must pass before merge. Currently no repo requires status checks, even biff and koch-trainer-swift which have CI. Depends on: branch protection rulesets + CI workflows.","status":"closed","priority":1,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-17T11:19:42.036205-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T14:34:58.653074-08:00","closed_at":"2026-02-19T14:34:58.653074-08:00","close_reason":"Branch protection rulesets with required status checks applied to all 11 repos","dependencies":[{"issue_id":"punt-kit-nz7","depends_on_id":"punt-kit-6q9","type":"blocks","created_at":"2026-02-17T11:20:39.167313-08:00","created_by":"\"jmf-pobox\""},{"issue_id":"punt-kit-nz7","depends_on_id":"punt-kit-h11","type":"blocks","created_at":"2026-02-17T11:20:39.292335-08:00","created_by":"\"jmf-pobox\""}]}
|
|
29
|
+
{"id":"punt-kit-pve","title":"Add dev workflow standards and project scaffolding tool","description":"DESIGN-GUIDANCE.md needs a dev workflow section based on Biff's CLAUDE.md patterns: workflow tiers (Forge/Feature Dev/Direct), branch discipline (feat/fix/refactor/docs prefixes), micro-commits, conventional commit messages, quality gates before every commit, pre-PR checklist, code review flow (Copilot review before merge), session close protocol, and design decision logs. Beyond documentation, this repo should become the scaffolding tool ('punt init' or similar) that bootstraps new projects with: templated CLAUDE.md, beads init, quality gate config (ruff/mypy/pytest), CI workflows, pyproject.toml or plugin.json skeleton, and correct naming conventions. Dependencies: feature-dev, claude-flow, feature-forge as workflow tools. Reference implementation: ~/Coding/biff/CLAUDE.md.","status":"closed","priority":2,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-17T10:08:32.960686-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-17T18:21:19.638403-08:00","closed_at":"2026-02-17T18:21:19.638403-08:00","close_reason":"Workflow standards added to workflow.md (10 sections). Scaffolding tool (punt init/audit) was already done."}
|
|
30
|
+
{"id":"punt-kit-r6j","title":"Investigate Entire.io commit-linked conversations","description":"Entire.io displays at startup: 'This conversation will be linked to your next commit.' Investigate:\n\n1. **How it works** — What mechanism links conversations to commits? Git hooks? Commit message metadata? External database?\n2. **What value it provides** — Traceability from code changes back to the reasoning/discussion that produced them. Useful for code review, debugging, onboarding.\n3. **How we could adopt it** — Should we use Entire.io directly, or build something similar? Could beads or session IDs serve a similar purpose?\n4. **Cross-project applicability** — Would this be valuable across all punt-labs repos or only specific ones?\n\nContext: Discovered during testing of entire.io. The SessionStart hook announces the linking capability.\n\n## Findings from langlearn-tts (2026-02-22)\n\nEntire.io is already installed and configured in langlearn-tts. Here's what we know:\n\n### Installation\n- Binary: ~/.local/bin/entire (v0.4.2, Go, darwin/arm64; v0.4.5 available)\n- Project data: .entire/ directory (logs, metadata per session UUID)\n- Git data: .git/entire-sessions/\u003cuuid\u003e.json (session archives, not version-controlled)\n\n### Hook Integration (.claude/settings.json)\nEntire.io uses Claude Code hooks at every major lifecycle event:\n- SessionStart → entire hooks claude-code session-start\n- SessionEnd → entire hooks claude-code session-end\n- UserPromptSubmit → entire hooks claude-code user-prompt-submit\n- Stop → entire hooks claude-code stop\n- PreToolUse (Task) → entire hooks claude-code pre-task\n- PostToolUse (Task) → entire hooks claude-code post-task\n- PostToolUse (TodoWrite) → entire hooks claude-code post-todo\n\n### Security\n- Explicit permission denial: Read(./.entire/metadata/**) — prevents Claude from reading session transcripts during sessions.\n\n### What It Captures\n- Each Claude Code session gets a UUID\n- Stores: user prompt, full conversation transcript (JSONL), AI-generated summary\n- Session archives in .git/entire-sessions/ (2MB+ per session)\n- Structured activity log with timestamps and phase transitions\n\n### Evidence of Value\n- One session captured the root cause analysis for langlearn-tts output path inconsistency (three independent _default_output_dir() implementations)\n- Session summary extracted the insight and linked to bead lltts-612\n- Provides searchable history of why changes were made\n\n### Open Questions\n- How exactly does it link to commits? (pre-commit hook? commit message annotation? external DB?)\n- What is the storage cost at scale? (2MB+ per session)\n- Should .entire/ be gitignored or version-controlled?\n- Is there overlap/conflict with beads workflow?\n- Should this be an org-wide standard or opt-in per project?\n\n## Patterns Relevant to Biff\n\nAll file references below are from ~/Coding/punt-labs/langlearn-tts/.\n\n### Session Identity\nEntire.io assigns every Claude Code session a UUID and tracks it as a first-class object. Biff already has session awareness (/tty, /who, /finger) — you can name a session and see what teammates are working on. Entire.io adds the content dimension: not just 'jfreeman is working on langlearn-tts' but 'jfreeman investigated output path inconsistencies, found three divergent implementations, created bead lltts-612.'\n\nIf Biff's /plan or /finger output could surface a session summary — even a one-liner — teammates would get much richer context about what's actually happening without asking.\n\nSee: .entire/metadata/b37a5cc6-a18f-4fe4-a5c5-264c5fb24322/summary.txt for an example auto-generated session summary.\n\n### Hook Architecture Comparison\nEntire.io hooks into every Claude Code lifecycle event to build its activity log. Biff already uses hooks too (SessionStart for setup, etc.), but for infrastructure rather than content capture. The pattern of hooking PostToolUse to capture what tools did (not just that they ran) is worth noting. For example, Biff could observe when a user sends a /wall or closes a bead and use that as a signal for presence/activity updates.\n\nSee: .claude/settings.json (hooks section) for the full hook configuration — SessionStart, SessionEnd, UserPromptSubmit, Stop, PreToolUse(Task), PostToolUse(Task, TodoWrite).\n\n### Auto-Generated Context\nEntire.io produces summaries after sessions end — distilled insights from full transcripts. For Biff, the analog would be automated status updates. Instead of manually running /plan 'investigating output paths', a session-end hook could generate a one-line summary of what was accomplished and update the user's Biff plan or send a notification to relevant channels.\n\nSee: .entire/logs/entire.log for the structured activity log with timestamps and phase transitions, and .git/entire-sessions/*.json for full session archives (~2MB each).\n\n### Security Model\nEntire.io explicitly denies Claude read access to its own metadata — preventing the agent from reading prior session transcripts during active sessions.\n\nSee: .claude/settings.json permissions section — deny: [Read(./.entire/metadata/**)].\n\n### The Interesting Question for Biff\nBiff's vocabulary is BSD Unix messaging — lightweight, human-scale, presence-aware. Entire.io is doing something adjacent: making AI work sessions observable. The overlap is in team awareness. If your teammate just spent 45 minutes debugging a tricky issue and Biff could surface 'jfreeman resolved: output dir inconsistency across 3 implementations' without them typing anything — that's the unix plan file updated automatically. The communication happens as a side effect of working, not as an interruption to it.","status":"open","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-22T20:26:39.804488-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T20:35:35.473157-08:00"}
|
|
31
|
+
{"id":"punt-kit-rsc","title":"punt install: register Claude Code plugin from PyPI package","description":"punt-kit is a hybrid: CLI installed from PyPI + Claude Code plugin with prompt files (commands/reconcile.md, .claude-plugin/plugin.json). Currently the plugin files ship in the repo but not in the PyPI distribution, so users who install via pip/uv don't get the /punt reconcile command.\n\nFix: include plugin files as package data in the wheel, and make 'punt install' register the plugin with Claude Code. The plugin should just work after 'pip install punt-kit \u0026\u0026 punt install' — no separate clone needed.\n\nReference implementation: biff solves the same hybrid problem (CLI + plugin). Study biff's install subcommand and package data configuration for the pattern to follow.\n\nFiles likely involved:\n- pyproject.toml (package data includes for .claude-plugin/ and commands/)\n- src/punt_kit/cli.py (punt install subcommand)\n- standards/distribution.md (may need update if this establishes a new pattern)","status":"closed","priority":2,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-20T12:23:49.699614-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T13:31:18.521667-08:00","closed_at":"2026-02-20T13:31:18.521667-08:00","close_reason":"Implemented punt install/uninstall. Plugin files ship in PyPI wheel via hatchling force-include. PR #10."}
|
|
32
|
+
{"id":"punt-kit-rt4","title":"Pin existing CI workflows to action SHAs","description":"Existing lint.yml and test.yml workflows across repos use short version tags (e.g. actions/checkout@v4) instead of full SHA pins per standards/github.md. Update all CI workflows in all repos to use SHA-pinned action references with version comments. Repos affected: biff, quarry, langlearn-tts, punt-kit, and Swift repos (koch-trainer-swift, quarry-menubar).","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-19T21:14:01.36511-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-19T23:42:50.366399-08:00","closed_at":"2026-02-19T23:42:50.366399-08:00","close_reason":"All CI workflows across all 11 repos now use SHA-pinned action references. biff (lint, test, hosted-nats), quarry (lint, test), langlearn-tts (ci) were the last to be pinned. koch-trainer-swift was done in an earlier PR. punt-kit, quarry-menubar, and all plugin/docs repos were already pinned."}
|
|
33
|
+
{"id":"punt-kit-t2a","title":"Add .biff to langlearn projects","description":"langlearn, langlearn-anki, langlearn-imagegen, langlearn-types all missing .biff team communication config. Standard content: [team] members=[jmf-pobox], [relay] url=tls://connect.ngs.global","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:54:21.46937-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.813916-08:00","closed_at":"2026-02-22T07:32:54.813916-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
|
34
|
+
{"id":"punt-kit-v9e","title":"Standard: init subcommand for per-repo activation","description":"CLI tools that need per-repo configuration should provide an init subcommand that creates the necessary config files. This is a cross-cutting CLI pattern.\n\n## What\nAn init subcommand (e.g. `quarry init`, `biff init`) that sets up per-repo configuration: creates config files, adds entries to .gitignore, and validates prerequisites. Idempotent — safe to run multiple times.\n\n## Why\nTools like quarry and biff need per-repo activation (quarry needs a collection config, biff needs namespace config). Currently users must manually create these. Both projects have independently identified this need (quarry-pil, biff-80z).\n\n## Standard definition needed\n- Subcommand: `\u003ctool\u003e init`\n- Behavior: create config files, update .gitignore, validate prerequisites\n- Idempotent: safe to re-run, does not overwrite user customizations\n- Output: report what was created/skipped\n- Document in standards/cli.md\n\n## Adoption tracking (project beads)\n- quarry-pil: Add init subcommand for per-repo configuration\n- biff-80z: Add init subcommand for per-repo activation","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-20T09:03:55.854317-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:25:13.443677-08:00","closed_at":"2026-02-20T09:25:13.443677-08:00","close_reason":"Standard defined in standards/cli.md — init subcommand added to Required Subcommands table with install-vs-init distinction, rules, and biff reference implementation. Adoption tracked by project beads: biff-80z, quarry-pil."}
|
|
35
|
+
{"id":"punt-kit-w8y","title":"Rewrite dungeon and prfaq install.sh as POSIX sh","description":"Rewrote both from bash to POSIX sh with marketplace install pattern. SHA-pinned in READMEs.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:27.127539-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:31.739044-08:00","closed_at":"2026-02-21T14:57:31.739044-08:00","close_reason":"Completed in standards sweep session"}
|
|
36
|
+
{"id":"punt-kit-ws7","title":"Add markdownlint-cli2.jsonc to missing repos","description":"Added to prfaq, feature-forge, z-spec, .github. Also added CI, markdownlint configs to claude-plugins.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:17.872533-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:22.489599-08:00","closed_at":"2026-02-21T14:57:22.489599-08:00","close_reason":"Completed in standards sweep session"}
|
|
37
|
+
{"id":"punt-kit-xwe","title":"Add permission cleanup phase to /punt reconcile","status":"closed","priority":2,"issue_type":"feature","owner":"jmf@pobox.com","created_at":"2026-02-22T07:49:03.584955-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:49:34.973325-08:00","closed_at":"2026-02-22T07:49:34.973325-08:00","close_reason":"Added Phase 6 (Clean Permission Bloat) to commands/reconcile.md"}
|
|
38
|
+
{"id":"punt-kit-y6u","title":"langlearn-tts install broken: path dep on langlearn-types","description":"uv tool install from git URL fails because [tool.uv.sources] declares punt-langlearn-types = { path = '../langlearn-types' }. uv tries to resolve this inside the cloned repo. punt-langlearn-types is not on PyPI. Affects install.sh for any non-developer. Workaround: editable install from local workspace. Fix: either publish langlearn-types to PyPI, use a git URL source override, or restructure the dependency.","status":"closed","priority":1,"issue_type":"bug","owner":"jmf@pobox.com","created_at":"2026-02-21T16:32:18.022742-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.807668-08:00","closed_at":"2026-02-22T07:32:54.807668-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
|
39
|
+
{"id":"punt-kit-yoy","title":"Add CLAUDE.md, CHANGELOG.md, CI to repos missing them","description":"CLAUDE.md: .github, claude-plugins. CHANGELOG.md: punt-kit, quarry-menubar, dungeon, feature-forge, z-spec. CI: claude-plugins docs.yml.","status":"closed","priority":2,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-21T14:57:31.864751-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-21T14:57:36.3645-08:00","closed_at":"2026-02-21T14:57:36.3645-08:00","close_reason":"Completed in standards sweep session"}
|
|
40
|
+
{"id":"punt-kit-ysn","title":"Add timeout-minutes to Python CI workflows","description":"Python CI workflows (lint.yml, test.yml) across biff, quarry, langlearn-tts, and punt-kit are missing timeout-minutes. The Swift repos and release workflows already have them. Add timeout-minutes: 10 to lint jobs and timeout-minutes: 10 to test jobs (matching the github.md standard: 10 min for lint, 20 min for tests — though Python tests are fast, 10 min is plenty).","status":"closed","priority":3,"issue_type":"task","owner":"jmf@pobox.com","created_at":"2026-02-20T06:28:35.51764-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-20T09:09:17.486838-08:00","closed_at":"2026-02-20T09:09:17.486838-08:00","close_reason":"Rolled out across all 4 Python repos (punt-kit, biff, quarry, langlearn-tts). PRs: punt-kit#5, biff#47, quarry#55, langlearn-tts#26 — all merged."}
|
|
41
|
+
{"id":"punt-kit-zud","title":"Investigate langlearn CI path dependency resolution","description":"langlearn pyproject.toml has [tool.uv.sources] path deps pointing to ../langlearn-types, ../langlearn-anki, etc. CI workflows do NOT clone these sibling repos before uv sync. Either CI is silently broken (smoke tests mask it) or uv falls back to PyPI. langlearn-anki correctly clones langlearn-types but langlearn does not clone any of its 4 path deps.","status":"closed","priority":2,"issue_type":"bug","owner":"jmf@pobox.com","created_at":"2026-02-21T14:54:25.785865-08:00","created_by":"\"jmf-pobox\"","updated_at":"2026-02-22T07:32:54.812744-08:00","closed_at":"2026-02-22T07:32:54.812744-08:00","close_reason":"Moved to langlearn beads — project-specific work, not org-level"}
|
punt_kit-0.1.0/.biff
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Punt Labs
|
|
2
|
+
|
|
3
|
+
Tools for engineers who work with AI. Open source. Quality-focused.
|
|
4
|
+
|
|
5
|
+
## About
|
|
6
|
+
|
|
7
|
+
Punt Labs builds software that keeps engineers in flow. Most of our tools work two ways: as standalone CLIs and as plugins or MCP servers inside Claude Code and Claude Desktop. Use them from the terminal or let your AI assistant use them for you. Our name comes from punting in Oxford: a casual way to give something a go.
|
|
8
|
+
|
|
9
|
+
Our design standards and project guide live in [punt-kit](https://github.com/punt-labs/punt-kit).
|
|
10
|
+
|
|
11
|
+
## Projects
|
|
12
|
+
|
|
13
|
+
### Product Planning
|
|
14
|
+
|
|
15
|
+
- [**PR/FAQ**](https://github.com/punt-labs/prfaq) `Claude Code` — Amazon's Working Backwards process in the terminal. Generate, review, stress-test, and iterate on product discovery documents with eight specialized agents, simulated review meetings, and compiled PDF output.
|
|
16
|
+
|
|
17
|
+
### Development
|
|
18
|
+
|
|
19
|
+
- [**Biff**](https://github.com/punt-labs/biff) `CLI` `Claude Code` — Team communication for engineers who never leave the terminal. Resurrects the BSD Unix communication vocabulary (`who`, `finger`, `write`, `plan`) as both CLI commands and MCP-native slash commands over a NATS relay. Humans and agents show up side by side.
|
|
20
|
+
- [**Quarry**](https://github.com/punt-labs/quarry) `CLI` `Claude Code` `Claude Desktop` `macOS` — Local semantic search across your documents. Index PDFs, images, spreadsheets, source code, and 30+ formats. Search by meaning, not keywords. Works as a standalone CLI, an MCP server, or through the [menu bar app](https://github.com/punt-labs/quarry-menubar). Runs entirely offline.
|
|
21
|
+
- [**Z Spec**](https://github.com/punt-labs/z-spec) `Claude Code` — Formal Z specifications for stateful systems. Extract specs from existing code (`code2model`) or generate code from specs (`model2code`). Type-check with fuzz, animate and model-check with ProB.
|
|
22
|
+
|
|
23
|
+
### Applications
|
|
24
|
+
|
|
25
|
+
- [**Dungeon**](https://github.com/punt-labs/dungeon) `Claude Code` — Text adventure prototype where Claude is the game master. No code runs, only prompts. Demonstrates what's possible with skills, MCP state management, and natural language as the parser.
|
|
26
|
+
- [**LangLearn TTS**](https://github.com/punt-labs/langlearn-tts) `CLI` `Claude Desktop` — Gives Claude the ability to speak. Pronounce words, generate audio flashcards, or run full language lessons with audio in 70+ languages. Works as a standalone CLI or an MCP server. Ships with 28 AI tutor personas across seven languages and four levels.
|
|
27
|
+
- [**Koch Trainer**](https://github.com/punt-labs/koch-trainer-swift) `iOS` — Morse code trainer using the Koch method. Receive/send training, QSO simulation, spaced repetition, and vocabulary practice for amateur radio operators. Built from a formal [Z Spec](https://github.com/punt-labs/z-spec) specification — an example of the design-to-code workflow our tools support.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
docs:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 10
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
15
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: "20"
|
|
18
|
+
- run: npx markdownlint-cli2 "**/*.md" "#node_modules"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 10
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
15
|
+
- uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
|
|
16
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- run: uv sync --frozen
|
|
20
|
+
- run: uv run ruff check .
|
|
21
|
+
- run: uv run ruff format --check .
|
|
22
|
+
- run: uv run mypy src/ tests/
|
|
23
|
+
- run: uv run pyright src/ tests/
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions: {}
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 10
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
steps:
|
|
17
|
+
- name: Validate tag ref
|
|
18
|
+
run: |
|
|
19
|
+
if [[ "$GITHUB_REF_NAME" != v* ]]; then
|
|
20
|
+
echo "::error::Release must be triggered by a v* tag push. For manual dispatch, use: gh workflow run release.yml --ref v1.2.3"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
24
|
+
- uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
|
|
25
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.13"
|
|
28
|
+
- run: uv build
|
|
29
|
+
- run: uvx twine check dist/*
|
|
30
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
retention-days: 1
|
|
35
|
+
|
|
36
|
+
testpypi:
|
|
37
|
+
needs: build
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
timeout-minutes: 10
|
|
40
|
+
environment: testpypi
|
|
41
|
+
permissions:
|
|
42
|
+
id-token: write
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
49
|
+
with:
|
|
50
|
+
repository-url: https://test.pypi.org/legacy/
|
|
51
|
+
|
|
52
|
+
test-install:
|
|
53
|
+
needs: testpypi
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
timeout-minutes: 10
|
|
56
|
+
steps:
|
|
57
|
+
- uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
|
|
58
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
59
|
+
with:
|
|
60
|
+
python-version: "3.13"
|
|
61
|
+
- name: Install from TestPyPI
|
|
62
|
+
run: |
|
|
63
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
64
|
+
for attempt in 1 2 3 4 5; do
|
|
65
|
+
echo "Attempt $attempt: installing punt-kit==$VERSION from TestPyPI..."
|
|
66
|
+
if uv pip install --system \
|
|
67
|
+
--index-url https://test.pypi.org/simple/ \
|
|
68
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
69
|
+
"punt-kit==$VERSION"; then
|
|
70
|
+
echo "Successfully installed punt-kit==$VERSION"
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
echo "Attempt $attempt failed, waiting 30s..."
|
|
74
|
+
sleep 30
|
|
75
|
+
done
|
|
76
|
+
echo "Failed to install punt-kit==$VERSION after 5 attempts"
|
|
77
|
+
exit 1
|
|
78
|
+
- name: Verify CLI
|
|
79
|
+
run: punt --help
|
|
80
|
+
|
|
81
|
+
pypi:
|
|
82
|
+
needs: test-install
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
timeout-minutes: 10
|
|
85
|
+
environment: release
|
|
86
|
+
permissions:
|
|
87
|
+
id-token: write
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
90
|
+
with:
|
|
91
|
+
name: dist
|
|
92
|
+
path: dist/
|
|
93
|
+
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 20
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
15
|
+
- uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
|
|
16
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- run: uv sync --frozen
|
|
20
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Nested git repos (independent projects)
|
|
2
|
+
lancedb/
|
|
3
|
+
|
|
4
|
+
# Python
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.pyc
|
|
7
|
+
.venv/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.mypy_cache/
|
|
12
|
+
.ruff_cache/
|
|
13
|
+
|
|
14
|
+
# Session scratch files (not part of the project)
|
|
15
|
+
session.md
|
|
16
|
+
|
|
17
|
+
.claude/
|
|
18
|
+
!.claude/settings.json
|
|
19
|
+
!.claude/hooks/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Disable line length — tables, URLs, and pattern descriptions routinely exceed any limit
|
|
3
|
+
"MD013": false,
|
|
4
|
+
// Disable table column style — compact pipes are fine
|
|
5
|
+
"MD060": false,
|
|
6
|
+
// Allow duplicate headings under different parents (CHANGELOG, ADR patterns)
|
|
7
|
+
"MD024": { "siblings_only": true },
|
|
8
|
+
// Allow img and p elements — needed for README screenshot layouts with width/align
|
|
9
|
+
"MD033": { "allowed_elements": ["img", "p"] }
|
|
10
|
+
}
|