welchost 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 (47) hide show
  1. welchost-0.1.0/.commitlintrc.yml +20 -0
  2. welchost-0.1.0/.cz.toml +8 -0
  3. welchost-0.1.0/.github/workflows/ci.yml +50 -0
  4. welchost-0.1.0/.github/workflows/homebrew-test.yml +18 -0
  5. welchost-0.1.0/.github/workflows/pr-check.yml +46 -0
  6. welchost-0.1.0/.github/workflows/release.yml +67 -0
  7. welchost-0.1.0/.gitignore +26 -0
  8. welchost-0.1.0/.pre-commit-config.yaml +11 -0
  9. welchost-0.1.0/CHANGELOG.md +152 -0
  10. welchost-0.1.0/CLAUDE.md +528 -0
  11. welchost-0.1.0/LICENSE +21 -0
  12. welchost-0.1.0/PKG-INFO +94 -0
  13. welchost-0.1.0/PUBLISHING.md +122 -0
  14. welchost-0.1.0/README.md +55 -0
  15. welchost-0.1.0/pyproject.toml +86 -0
  16. welchost-0.1.0/src/welchost/__init__.py +1 -0
  17. welchost-0.1.0/src/welchost/cli.py +149 -0
  18. welchost-0.1.0/src/welchost/config.py +169 -0
  19. welchost-0.1.0/src/welchost/detect.py +86 -0
  20. welchost-0.1.0/src/welchost/generator.py +332 -0
  21. welchost-0.1.0/src/welchost/ornaments.py +38 -0
  22. welchost-0.1.0/src/welchost/render.py +203 -0
  23. welchost-0.1.0/src/welchost/templates/welcome.zsh.j2 +6 -0
  24. welchost-0.1.0/src/welchost/templates/welcome_banner.py.j2 +233 -0
  25. welchost-0.1.0/src/welchost/themes.py +103 -0
  26. welchost-0.1.0/src/welchost/tui/__init__.py +0 -0
  27. welchost-0.1.0/src/welchost/tui/app.py +94 -0
  28. welchost-0.1.0/src/welchost/tui/dev_watcher.py +33 -0
  29. welchost-0.1.0/src/welchost/tui/fonts.py +51 -0
  30. welchost-0.1.0/src/welchost/tui/logo.py +125 -0
  31. welchost-0.1.0/src/welchost/tui/screens/__init__.py +0 -0
  32. welchost-0.1.0/src/welchost/tui/screens/main_menu.py +260 -0
  33. welchost-0.1.0/src/welchost/tui/screens/modals.py +84 -0
  34. welchost-0.1.0/src/welchost/tui/screens/step_color.py +74 -0
  35. welchost-0.1.0/src/welchost/tui/screens/step_confirm.py +65 -0
  36. welchost-0.1.0/src/welchost/tui/screens/step_decoration.py +91 -0
  37. welchost-0.1.0/src/welchost/tui/screens/step_text_font.py +63 -0
  38. welchost-0.1.0/src/welchost/tui/screens/theme_gallery.py +81 -0
  39. welchost-0.1.0/src/welchost/tui/screens/wizard.py +126 -0
  40. welchost-0.1.0/src/welchost/tui/widgets.py +190 -0
  41. welchost-0.1.0/tests/conftest.py +35 -0
  42. welchost-0.1.0/tests/test_cli.py +73 -0
  43. welchost-0.1.0/tests/test_config.py +81 -0
  44. welchost-0.1.0/tests/test_detect.py +44 -0
  45. welchost-0.1.0/tests/test_dev_mode.py +65 -0
  46. welchost-0.1.0/tests/test_generator.py +145 -0
  47. welchost-0.1.0/tests/test_themes.py +55 -0
@@ -0,0 +1,20 @@
1
+ extends:
2
+ - conventional
3
+ rules:
4
+ type-enum:
5
+ - 2
6
+ - always
7
+ - [feat, fix, chore, docs, test, refactor, perf, ci, build]
8
+ scope-empty:
9
+ - 0
10
+ subject-empty:
11
+ - 2
12
+ - never
13
+ subject-max-length:
14
+ - 2
15
+ - always
16
+ - 100
17
+ header-max-length:
18
+ - 2
19
+ - always
20
+ - 120
@@ -0,0 +1,8 @@
1
+ [tool.commitizen]
2
+ name = "cz_conventional_commits"
3
+ version = "0.1.0"
4
+ version_files = [
5
+ "src/welchost/__init__.py:__version__",
6
+ "pyproject.toml:version",
7
+ ]
8
+ tag_format = "v$version"
@@ -0,0 +1,50 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ lint-commits:
15
+ name: Lint commit messages
16
+ runs-on: ubuntu-latest
17
+ if: github.event_name == 'pull_request'
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+ - uses: wagoid/commitlint-github-action@v6
23
+ with:
24
+ configFile: .commitlintrc.yml
25
+
26
+ lint:
27
+ name: Lint
28
+ runs-on: macos-latest
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.13"
34
+ - run: pip install ruff
35
+ - run: ruff check src/ tests/
36
+ - run: ruff format --check src/ tests/
37
+
38
+ test:
39
+ name: Test (Python ${{ matrix.python-version }})
40
+ runs-on: macos-latest
41
+ strategy:
42
+ matrix:
43
+ python-version: ["3.11", "3.12", "3.13"]
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: actions/setup-python@v5
47
+ with:
48
+ python-version: ${{ matrix.python-version }}
49
+ - run: pip install -e ".[dev]"
50
+ - run: pytest --tb=short -q
@@ -0,0 +1,18 @@
1
+ name: Homebrew Formula Test
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [published]
7
+
8
+ jobs:
9
+ test-brew:
10
+ name: Test Homebrew install
11
+ runs-on: macos-latest
12
+ steps:
13
+ - name: Test formula
14
+ run: |
15
+ brew tap scoobynko/welchost
16
+ brew install welchost
17
+ welchost version
18
+ welchost doctor
@@ -0,0 +1,46 @@
1
+ name: PR Check
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ types: [opened, synchronize, reopened, edited]
7
+
8
+ jobs:
9
+ commit-lint:
10
+ name: Validate commit messages
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+ - uses: wagoid/commitlint-github-action@v6
17
+ with:
18
+ configFile: .commitlintrc.yml
19
+ failOnWarnings: false
20
+ helpURL: "https://www.conventionalcommits.org"
21
+
22
+ changeset-check:
23
+ name: Check release notes
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 0
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.13"
32
+ - name: Check conventional commit on PR title
33
+ env:
34
+ PR_TITLE: ${{ github.event.pull_request.title }}
35
+ run: |
36
+ python -c "
37
+ import re, os, sys
38
+ title = os.environ['PR_TITLE']
39
+ pattern = r'^(feat|fix|chore|docs|test|refactor|perf|ci|build)(\(.+\))?!?: .{1,100}$'
40
+ if not re.match(pattern, title):
41
+ print(f'PR title does not follow conventional commits: {title}')
42
+ print('Expected: type(scope): description')
43
+ print('Example: feat(tui): add gradient preview')
44
+ sys.exit(1)
45
+ print(f'PR title OK: {title}')
46
+ "
@@ -0,0 +1,67 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ concurrency:
8
+ group: ${{ github.workflow }}-${{ github.ref }}
9
+
10
+ jobs:
11
+ release:
12
+ name: Release
13
+ # Must be Linux: python-semantic-release is a Docker container action, which
14
+ # only runs on Linux runners. Wheel build + PyPI publish are platform-agnostic;
15
+ # the macOS-only `brew install` check lives in homebrew-test.yml.
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ contents: write
19
+ id-token: write
20
+ env:
21
+ # Surfaced at job level so steps can gate on its presence in `if:`.
22
+ HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
23
+
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0
28
+ token: ${{ secrets.GITHUB_TOKEN }}
29
+
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.13"
33
+
34
+ - name: Install dependencies
35
+ run: pip install -e ".[dev]"
36
+
37
+ - name: Lint
38
+ run: ruff check src/ tests/
39
+
40
+ - name: Test
41
+ run: pytest --tb=short -q
42
+
43
+ - name: Python Semantic Release
44
+ id: release
45
+ uses: python-semantic-release/python-semantic-release@v9
46
+ with:
47
+ github_token: ${{ secrets.GITHUB_TOKEN }}
48
+
49
+ - name: Publish to PyPI
50
+ if: steps.release.outputs.released == 'true'
51
+ uses: pypa/gh-action-pypi-publish@release/v1
52
+ with:
53
+ password: ${{ secrets.PYPI_TOKEN }}
54
+
55
+ - name: Update Homebrew tap
56
+ # Skips until the tap token is configured, so a PyPI-only release stays green.
57
+ if: steps.release.outputs.released == 'true' && env.HOMEBREW_TAP_TOKEN != ''
58
+ uses: mislav/bump-homebrew-formula-action@v3
59
+ with:
60
+ formula-name: welchost
61
+ formula-path: Formula/welchost.rb
62
+ homebrew-tap: scoobynko/homebrew-welchost
63
+ base-branch: main
64
+ download-url: https://files.pythonhosted.org/packages/source/w/welchost/welchost-${{ steps.release.outputs.version }}.tar.gz
65
+ commit-message: "chore: bump welchost to {{version}}"
66
+ env:
67
+ COMMITTER_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
@@ -0,0 +1,26 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+ .eggs/
8
+
9
+ # Virtualenvs
10
+ .venv/
11
+ venv/
12
+
13
+ # Welchost dev sandbox
14
+ dev-home/
15
+ *.welchost.bak*
16
+
17
+ # Tooling
18
+ .pytest_cache/
19
+ .ruff_cache/
20
+ .coverage
21
+ htmlcov/
22
+
23
+ # OS / editor
24
+ .DS_Store
25
+ .idea/
26
+ .vscode/
@@ -0,0 +1,11 @@
1
+ repos:
2
+ - repo: https://github.com/compilerla/conventional-pre-commit
3
+ rev: v3.4.0
4
+ hooks:
5
+ - id: conventional-pre-commit
6
+ stages: [commit-msg]
7
+ - repo: https://github.com/astral-sh/ruff-pre-commit
8
+ rev: v0.8.0
9
+ hooks:
10
+ - id: ruff
11
+ - id: ruff-format
@@ -0,0 +1,152 @@
1
+ # CHANGELOG
2
+
3
+
4
+ ## v0.1.0 (2026-06-12)
5
+
6
+ ### Bug Fixes
7
+
8
+ - **ci**: Run release on ubuntu (semantic-release needs a Linux runner)
9
+ ([`144618e`](https://github.com/scoobynko/welchost/commit/144618e2e8287d01162c2fcdb926530607b5144e))
10
+
11
+ python-semantic-release is a Docker container action and fails with "Container action is only
12
+ supported on Linux" on macos-latest. The release job is platform-agnostic; the macOS brew check
13
+ stays in homebrew-test.yml.
14
+
15
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
16
+
17
+ ### Chores
18
+
19
+ - Init project structure
20
+ ([`1bc53f8`](https://github.com/scoobynko/welchost/commit/1bc53f83b662b3bb90cee8ffac9215922c37adfe))
21
+
22
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23
+
24
+ ### Continuous Integration
25
+
26
+ - Skip Homebrew bump until the tap token is configured
27
+ ([`a7c101c`](https://github.com/scoobynko/welchost/commit/a7c101c8e433c78d20234d515d2528d1854f1dd1))
28
+
29
+ Gate the formula-bump step on HOMEBREW_TAP_TOKEN so a PyPI-only release stays green; the step lights
30
+ up automatically once the tap secret exists.
31
+
32
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
33
+
34
+ ### Documentation
35
+
36
+ - Add CHANGELOG for v0.1.0
37
+ ([`4b2c7a4`](https://github.com/scoobynko/welchost/commit/4b2c7a4dc539d07a36136da3573e077f16c1c20b))
38
+
39
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40
+
41
+ - Add CLAUDE.md project specification
42
+ ([`cdaf441`](https://github.com/scoobynko/welchost/commit/cdaf441fe467bab0dad0c880f47f0fb55c41d2f4))
43
+
44
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45
+
46
+ - Add first-time publishing & release-setup runbook
47
+ ([`c6e0dde`](https://github.com/scoobynko/welchost/commit/c6e0dded4cefc49f969336e51d2a479135529a44))
48
+
49
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50
+
51
+ - Update spec for alignment, gradients, ornaments, and shell-chain guards
52
+ ([`4ea99f9`](https://github.com/scoobynko/welchost/commit/4ea99f9a921d6244706d000f8376f26102042612))
53
+
54
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55
+
56
+ ### Features
57
+
58
+ - **core**: Banner alignment, directional gradients, ornaments + hardening
59
+ ([`403d85c`](https://github.com/scoobynko/welchost/commit/403d85c30c77f36d62a160b1ac28405dc1380580))
60
+
61
+ Replace banner.size with banner.align (left/center/right) and add per-block directional gradients
62
+ (horizontal/vertical/diagonal) and predefined flanking ASCII ornaments (new ornaments.py).
63
+ render.py and the generated welcome_banner.py share identical block-gradient/flank/align logic so
64
+ the preview stays WYSIWYG.
65
+
66
+ Security & robustness for public distribution: - clamp
67
+ align/color_mode/gradient.direction/border_style to their schema enums before baking into the
68
+ generated script (closes code-injection via a hand-edited/shared welchost.toml) - resolve_color
69
+ always returns a 3-tuple, falling back to gray on partial or malformed hex (no more unpack crash
70
+ in the live preview) - generated welcome.zsh only runs when python3 is present; the .zshrc line
71
+ also guards on the shim being readable, so a missing interpreter or shim can never spam errors on
72
+ every shell - load_config tolerates a corrupt welchost.toml (returns None) instead of crashing the
73
+ TUI/CLI on launch - memoize pyfiglet rendering; route the sentinel marker through one constant
74
+
75
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76
+
77
+ - **core**: Detect, config, themes, generator, cli + templates
78
+ ([`fba2455`](https://github.com/scoobynko/welchost/commit/fba24553f2fbb47d983d6640718f16800942d4d8))
79
+
80
+ - detect.py: DEV-aware path resolution + Ghostty detection - config.py: WelchostConfig dataclass,
81
+ lossless TOML round-trip - themes.py: 12 built-in themes - generator.py: pyfiglet render,
82
+ self-contained banner script, idempotent .zshrc sentinel + backup, reset - cli.py: Typer app
83
+ (config/preview/reset/doctor/version) with --dev callback - templates: welcome.zsh.j2,
84
+ welcome_banner.py.j2 (pure-Python ANSI)
85
+
86
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87
+
88
+ - **tui**: Keyboard-only redesign — color picker, modals, logo, fixes
89
+ ([`1c127f5`](https://github.com/scoobynko/welchost/commit/1c127f5ee9590ad77b0b7fa69b722bdaf815a030))
90
+
91
+ - ColorField widget: preset swatches + custom-hex dropdown, reused across the color and decoration
92
+ steps - ConfirmModal: keyboard-driven yes/no overlay; delete and create-new flows route through
93
+ one shared _Menu.confirm helper - unify reset/delete behind one confirm_reset (consistent wording,
94
+ removed paths surfaced); retire the divergent full-screen ResetScreen - centralize config
95
+ lifecycle on the app (adopt_config/clear_config/ new_draft) so the menu always reflects whether a
96
+ config exists - levitating logo: gentle 2-axis idle hover; wordmark render cached - wizard: sticky
97
+ nav (back left / next-save far right), step content height:auto so tall steps (e.g. gradient
98
+ direction) scroll fully, and each step resets to the top on switch - hide the border-color field
99
+ when border style is "none"; shared apply_visibility helper for conditional fields
100
+
101
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
102
+
103
+ - **tui**: Pixel logo, list-based template picker, no emoji
104
+ ([`c39abed`](https://github.com/scoobynko/welchost/commit/c39abedee99ce49c2f1f19685246e4181f3d7886))
105
+
106
+ - logo: pixel-art ghost + double_blocky wordmark (clear W, pixel edges) - replace all emojis with
107
+ accent block glyphs - template picker: vertical list + live preview (smaller, easy ↑/↓ nav) and
108
+ enter opens the wizard at step 1 so text/font stay editable - docs: update keyboard-nav section
109
+
110
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
111
+
112
+ - **tui**: Redesign — 6 templates, logo, keyboard-only nav, fix save
113
+ ([`1ebdbf2`](https://github.com/scoobynko/welchost/commit/1ebdbf29eae9bf83152c99ae6fe3161bacae19f7))
114
+
115
+ - themes: 12 -> 6 curated (claude/codex filled, ghost, matrix, sunset, mono), terracotta accent;
116
+ fixes invalid pyfiglet font names - generator: build_figlet falls back to standard on missing
117
+ font; write files atomically (render both before writing) so a bad font can't half-install - tui:
118
+ first-screen logo (pagga wordmark + ghost + prompt), more padding, minimalist; keyboard-only —
119
+ gallery arrows/hjkl, wizard ctrl+arrows + ctrl+s, color presets/mode as RadioSets (no click-only
120
+ buttons) - tests updated for 6 templates + font fallback/validity
121
+
122
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
123
+
124
+ - **tui**: Textual app, theme gallery, 4-step wizard, live preview
125
+ ([`d43047b`](https://github.com/scoobynko/welchost/commit/d43047b3a193b95b82bdc99df239f8027c1fd000))
126
+
127
+ - render.py: shared Rich banner rendering (CLI + TUI WYSIWYG); cli refactored to use it - app.py:
128
+ WelchostApp holding a live WelchostConfig model; refresh_preview - main_menu: MainMenu/EditMenu +
129
+ Doctor/Preview/Reset screens - theme_gallery: 3-col grid of 12 live theme previews, search,
130
+ enter/c - wizard: 4-step container with progress + shared live BannerPreview - steps:
131
+ text+font(571 searchable), color(solid/gradient+swatches), decoration+info toggles,
132
+ confirm+install - dev_watcher: watchdog hot reload (DEV only)
133
+
134
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
135
+
136
+ ### Testing
137
+
138
+ - Cli, config, generator, detect, dev-mode, themes suites
139
+ ([`faabe76`](https://github.com/scoobynko/welchost/commit/faabe768faf4c608dec0f9ea6eef278be5d1b86d))
140
+
141
+ 63 tests: sentinel idempotency, DEV sandbox isolation, lossless config round-trip, all 12 theme
142
+ fonts valid, self-contained banner script.
143
+
144
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
145
+
146
+ - Cover alignment, gradient direction, ornaments, and config tolerance
147
+ ([`de802ab`](https://github.com/scoobynko/welchost/commit/de802ab373352f9a05d656a12a7ca48afab88c25))
148
+
149
+ Round-trip + defaults for align/direction/ornament, theme ornament-name validation (mirrors the font
150
+ check), gradient-direction baking, and that a legacy/removed key loads without crashing.
151
+
152
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>