Skip to content

Commit 8f4b8f9

Browse files
committed
Add Windows packaging & installer support
Add Windows installation and packaging support: introduce scripts/install_windows.ps1 for Windows installs and scripts/prepare_windows_packaging.py to generate Scoop manifest and a winget submission helper. Add packaging artifacts (packaging/scoop/lore-book.json, packaging/winget/submission-1.3.0.md) and a windows smoke CI workflow (.github/workflows/windows-smoke.yml). Update release workflow to build a local sdist and prepare/commit Windows packaging artifacts during release. Update docs/README/site install pages to document Windows install options and use the Python launcher. Small CLI tweaks: recommend using "python -m pip" for upgrades and add cross-platform clipboard detection (PowerShell Get-Clipboard, pwsh, pbpaste, xclip) for relic capture.
1 parent 3cce496 commit 8f4b8f9

File tree

10 files changed

+417
-15
lines changed

10 files changed

+417
-15
lines changed

.github/workflows/release.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ jobs:
4949
--version "${{ inputs.version }}" \
5050
--github-output "$GITHUB_OUTPUT"
5151
52+
- name: Build local sdist for packaging hashes
53+
run: |
54+
python -m pip install --upgrade pip build
55+
python -m build --sdist
56+
57+
- name: Prepare Windows packaging artifacts
58+
id: windows_packaging
59+
run: |
60+
python scripts/prepare_windows_packaging.py \
61+
--version "${{ steps.prep.outputs.version }}" \
62+
--repo "${{ github.repository }}" \
63+
--sdist-file "dist/lore_book-${{ steps.prep.outputs.version }}.tar.gz" \
64+
--github-output "$GITHUB_OUTPUT"
65+
5266
- name: Validate tag does not already exist
5367
run: |
5468
if git rev-parse -q --verify "refs/tags/${{ steps.prep.outputs.tag }}" >/dev/null; then
@@ -64,7 +78,7 @@ jobs:
6478
run: |
6579
git config user.name "github-actions[bot]"
6680
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
67-
git add src/lore/__init__.py CHANGELOG.md
81+
git add src/lore/__init__.py CHANGELOG.md packaging/scoop/lore-book.json packaging/winget/submission-${{ steps.prep.outputs.version }}.md
6882
git commit -m "chore(release): ${{ steps.prep.outputs.version }}"
6983
git tag "${{ steps.prep.outputs.tag }}"
7084
git push origin HEAD
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Windows Smoke
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
8+
concurrency:
9+
group: windows-smoke-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
smoke:
14+
runs-on: windows-latest
15+
timeout-minutes: 15
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
20+
21+
- name: Setup Python
22+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
23+
with:
24+
python-version: "3.12"
25+
26+
- name: Install package
27+
shell: pwsh
28+
run: |
29+
python -m pip install --upgrade pip setuptools wheel
30+
python -m pip install .
31+
32+
- name: Run smoke checks
33+
shell: pwsh
34+
run: |
35+
lore version
36+
37+
$testRepo = Join-Path $env:RUNNER_TEMP "lore-smoke-project"
38+
New-Item -ItemType Directory -Path $testRepo -Force | Out-Null
39+
Set-Location $testRepo
40+
41+
lore init .
42+
lore add facts "windows smoke memory"
43+
lore trust refresh --dry-run
44+
lore export --format chronicle
45+
46+
if (-not (Test-Path (Join-Path $testRepo "CHRONICLE.md"))) {
47+
throw "CHRONICLE.md was not generated"
48+
}

README.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,52 @@ Exports are atomic — a crash mid-write never leaves a partial file.
9999
pip install lore-book
100100
```
101101

102+
### Windows (recommended)
103+
104+
Use the Python launcher so the command works consistently across Windows setups:
105+
106+
```powershell
107+
py -m pip install --upgrade lore-book
108+
```
109+
110+
If you prefer isolated CLI installs, `pipx` is the smoothest option on Windows:
111+
112+
```powershell
113+
py -m pip install --user pipx
114+
py -m pipx ensurepath
115+
pipx install lore-book
116+
```
117+
118+
If you are installing from this repository, use the bootstrap script:
119+
120+
```powershell
121+
powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1
122+
```
123+
124+
Optional modes:
125+
126+
```powershell
127+
# Force plain pip install mode
128+
powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -Mode pip
129+
130+
# Install from local source path via pipx
131+
powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -SourcePath .
132+
```
133+
134+
### Windows package managers
135+
136+
`pipx install lore-book` remains the easiest path for most users.
137+
138+
This repo now generates Windows packaging artifacts during release:
139+
140+
- Scoop manifest: `packaging/scoop/lore-book.json`
141+
- winget submission helper: `packaging/winget/submission-<version>.md`
142+
143+
After each release, use these to publish:
144+
145+
1. Submit `packaging/scoop/lore-book.json` to your Scoop bucket repository.
146+
2. Use `packaging/winget/submission-<version>.md` to open/update a PR in `microsoft/winget-pkgs`.
147+
102148
For local development:
103149

104150
```sh
@@ -145,7 +191,7 @@ Preview locally:
145191

146192
```sh
147193
cd docs
148-
python3 -m http.server 8000
194+
python -m http.server 8000
149195
```
150196

151197
Then open:
@@ -218,7 +264,7 @@ lore relic capture --git-diff --title "Pre-deploy changes"
218264
# Capture the last N commits (messages + diffs)
219265
lore relic capture --git-log 5 --title "Sprint 12 wrap-up"
220266

221-
# Read from clipboard (macOS: pbpaste, Linux: xclip)
267+
# Read from clipboard (Windows: PowerShell Get-Clipboard, macOS: pbpaste, Linux: xclip)
222268
lore relic capture --clipboard --title "Slack thread on rate limiting"
223269

224270
# Pipe anything in

docs/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,14 @@ <h3>Distill</h3>
148148
<!-- ══ INCANTATIONS ══ -->
149149
<section class="parchment">
150150
<h2><span class="rune">🜏</span> Incantations</h2>
151+
<h3>Install on Windows (easy path)</h3>
152+
<div class="incantation"><span class="comment"># Use pipx for a clean CLI install</span><br><span class="cmd">py -m pip install --user pipx</span><br><span class="cmd">py -m pipx ensurepath</span><br><span class="cmd">pipx install lore-book</span></div>
153+
<h3>Install from this repo on Windows</h3>
154+
<div class="incantation"><span class="cmd">powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1</span></div>
151155
<h3>Install via Homebrew</h3>
152156
<div class="incantation"><span class="comment"># Bind the tap</span><br><span class="cmd">brew tap</span> <span class="arg">cptplastic/lore-book</span><br><span class="cmd">brew install</span> <span class="arg">lore-book</span></div>
153157
<h3>Install via pip</h3>
154-
<div class="incantation"><span class="cmd">pip install</span> <span class="arg">lore-book</span></div>
158+
<div class="incantation"><span class="cmd">python -m pip install</span> <span class="arg">lore-book</span></div>
155159
<h3>Cast your first spells</h3>
156160
<div class="incantation"><span class="comment"># Record a decision</span><br><span class="cmd">lore add</span> <span class="arg">decisions</span> <span class="arg">"Use PostgreSQL — we need JSONB and row-level locking"</span><br><br><span class="comment"># Record a fact</span><br><span class="cmd">lore add</span> <span class="arg">facts</span> <span class="arg">"Auth service is the sole issuer of JWTs — never bypass it"</span><br><br><span class="comment"># Publish to all AI instruction files</span><br><span class="cmd">lore export</span></div>
157161
</section>

packaging/scoop/lore-book.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"version": "1.3.0",
3+
"description": "The spellbook for your codebase - chronicle decisions, context, and lessons your AI tools can read.",
4+
"homepage": "https://github.com/CptPlastic/lore-book",
5+
"license": "FSL-1.1-MIT",
6+
"depends": "python",
7+
"architecture": {
8+
"64bit": {
9+
"url": "https://files.pythonhosted.org/packages/source/l/lore-book/lore-book-1.3.0.tar.gz",
10+
"hash": "cd09aab4053883dcce462876144ca1547fc25b38fe8e9179e758316aa08d2f47"
11+
}
12+
},
13+
"checkver": "https://pypi.org/pypi/lore-book/json",
14+
"autoupdate": {
15+
"architecture": {
16+
"64bit": {
17+
"url": "https://files.pythonhosted.org/packages/source/l/lore-book/lore-book-$version.tar.gz"
18+
}
19+
}
20+
},
21+
"pre_install": [
22+
"$pkg = \"lore-book==1.3.0\"",
23+
"python -m pip install --user --upgrade $pkg",
24+
"Set-Content -Path \"$dir\\lore.cmd\" -Value \"@echo off`r`npython -m lore.cli %*\" -Encoding Ascii"
25+
],
26+
"pre_uninstall": [
27+
"python -m pip uninstall -y lore-book"
28+
],
29+
"bin": "lore.cmd"
30+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# winget submission helper for lore-book 1.3.0
2+
3+
Generated: 2026-03-25
4+
5+
## Package metadata
6+
7+
- PackageIdentifier: CptPlastic.LoreBook
8+
- PackageVersion: 1.3.0
9+
- Publisher: CptPlastic
10+
- PackageName: lore-book
11+
- License: FSL-1.1-MIT
12+
- InstallerUrl: https://files.pythonhosted.org/packages/source/l/lore-book/lore-book-1.3.0.tar.gz
13+
- InstallerSha256: cd09aab4053883dcce462876144ca1547fc25b38fe8e9179e758316aa08d2f47
14+
15+
## Notes
16+
17+
`lore-book` is a Python CLI package. A direct winget installer is not auto-published from this repo.
18+
Use this file as the source of truth for opening/updating a PR in `microsoft/winget-pkgs`.
19+
20+
## Recommended submission flow
21+
22+
1. Install wingetcreate.
23+
2. Create or update a manifest for `CptPlastic.LoreBook` using the URL/hash above.
24+
3. Open a PR in `microsoft/winget-pkgs`.
25+
26+
Reference repository: https://github.com/CptPlastic/lore-book

scripts/install_windows.ps1

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
[CmdletBinding()]
2+
param(
3+
[ValidateSet("pipx", "pip")]
4+
[string]$Mode = "pipx",
5+
[string]$SourcePath
6+
)
7+
8+
$ErrorActionPreference = "Stop"
9+
10+
function Test-Command {
11+
param([Parameter(Mandatory = $true)][string]$Name)
12+
return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
13+
}
14+
15+
function Invoke-Py {
16+
param([Parameter(Mandatory = $true)][string[]]$Args)
17+
if (Test-Command "py") {
18+
& py @Args
19+
return
20+
}
21+
if (Test-Command "python") {
22+
& python @Args
23+
return
24+
}
25+
throw "Python was not found. Install Python 3.10+ from https://www.python.org/downloads/windows/ and re-run this script."
26+
}
27+
28+
Write-Host "[lore/windows] Bootstrap starting (mode=$Mode)"
29+
30+
if ($Mode -eq "pipx") {
31+
Write-Host "[lore/windows] Installing/upgrading pip + pipx"
32+
Invoke-Py -Args @("-m", "pip", "install", "--user", "--upgrade", "pip", "pipx")
33+
34+
Write-Host "[lore/windows] Ensuring pipx path"
35+
Invoke-Py -Args @("-m", "pipx", "ensurepath")
36+
37+
if ([string]::IsNullOrWhiteSpace($SourcePath)) {
38+
Write-Host "[lore/windows] Installing lore-book from PyPI via pipx"
39+
Invoke-Py -Args @("-m", "pipx", "install", "--force", "lore-book")
40+
}
41+
else {
42+
Write-Host "[lore/windows] Installing lore-book from source path: $SourcePath"
43+
Invoke-Py -Args @("-m", "pipx", "install", "--force", $SourcePath)
44+
}
45+
46+
Write-Host "[lore/windows] Verifying CLI"
47+
Invoke-Py -Args @("-m", "pipx", "run", "--spec", "lore-book", "lore", "version")
48+
}
49+
else {
50+
if ([string]::IsNullOrWhiteSpace($SourcePath)) {
51+
Write-Host "[lore/windows] Installing lore-book from PyPI via pip"
52+
Invoke-Py -Args @("-m", "pip", "install", "--user", "--upgrade", "lore-book")
53+
}
54+
else {
55+
Write-Host "[lore/windows] Installing lore-book from source path: $SourcePath"
56+
Invoke-Py -Args @("-m", "pip", "install", "--user", "--upgrade", $SourcePath)
57+
}
58+
59+
Write-Host "[lore/windows] Verifying package import"
60+
Invoke-Py -Args @("-c", "import lore; print(f'lore {lore.__version__}')")
61+
}
62+
63+
Write-Host "[lore/windows] Install complete."
64+
Write-Host "[lore/windows] If 'lore' is not recognized yet, open a new terminal session."

0 commit comments

Comments
 (0)