Skip to content

Commit 6344861

Browse files
phernandezclaude
andauthored
feat: v0.13.0 pre (#122)
Signed-off-by: phernandez <paul@basicmachines.co> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5ec4087 commit 6344861

116 files changed

Lines changed: 13130 additions & 2155 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/dev-release.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Dev Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch: # Allow manual triggering
7+
8+
jobs:
9+
dev-release:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
id-token: write
13+
contents: write
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install uv
26+
run: |
27+
pip install uv
28+
29+
- name: Install dependencies and build
30+
run: |
31+
uv venv
32+
uv sync
33+
uv build
34+
35+
- name: Check if this is a dev version
36+
id: check_version
37+
run: |
38+
VERSION=$(uv run python -c "import basic_memory; print(basic_memory.__version__)")
39+
echo "version=$VERSION" >> $GITHUB_OUTPUT
40+
if [[ "$VERSION" == *"dev"* ]]; then
41+
echo "is_dev=true" >> $GITHUB_OUTPUT
42+
echo "Dev version detected: $VERSION"
43+
else
44+
echo "is_dev=false" >> $GITHUB_OUTPUT
45+
echo "Release version detected: $VERSION, skipping dev release"
46+
fi
47+
48+
- name: Publish dev version to PyPI
49+
if: steps.check_version.outputs.is_dev == 'true'
50+
uses: pypa/gh-action-pypi-publish@release/v1
51+
with:
52+
password: ${{ secrets.PYPI_TOKEN }}
53+
skip-existing: true # Don't fail if version already exists

.github/workflows/release.yml

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,60 @@
11
name: Release
22

33
on:
4-
workflow_dispatch:
5-
inputs:
6-
version_type:
7-
description: 'Type of version bump (major, minor, patch)'
8-
required: true
9-
default: 'patch'
10-
type: choice
11-
options:
12-
- patch
13-
- minor
14-
- major
4+
push:
5+
tags:
6+
- 'v*' # Trigger on version tags like v1.0.0, v0.13.0, etc.
157

168
jobs:
179
release:
1810
runs-on: ubuntu-latest
19-
concurrency: release
2011
permissions:
2112
id-token: write
2213
contents: write
23-
outputs:
24-
released: ${{ steps.release.outputs.released }}
25-
tag: ${{ steps.release.outputs.tag }}
2614

2715
steps:
2816
- uses: actions/checkout@v4
2917
with:
3018
fetch-depth: 0
3119

32-
- name: Python Semantic Release
33-
id: release
34-
uses: python-semantic-release/python-semantic-release@master
35-
with:
36-
github_token: ${{ secrets.GITHUB_TOKEN }}
37-
38-
- name: Publish to PyPI
39-
uses: pypa/gh-action-pypi-publish@release/v1
40-
if: steps.release.outputs.released == 'true'
41-
with:
42-
password: ${{ secrets.PYPI_TOKEN }}
43-
44-
- name: Publish to GitHub Release Assets
45-
uses: python-semantic-release/publish-action@v9.8.9
46-
if: steps.release.outputs.released == 'true'
47-
with:
48-
github_token: ${{ secrets.GITHUB_TOKEN }}
49-
tag: ${{ steps.release.outputs.tag }}
50-
51-
build-macos:
52-
needs: release
53-
if: needs.release.outputs.released == 'true'
54-
runs-on: macos-latest
55-
steps:
56-
- uses: actions/checkout@v4
57-
with:
58-
ref: ${{ needs.release.outputs.tag }}
59-
60-
- name: Set up Python "3.12"
61-
uses: actions/setup-python@v4
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
6222
with:
6323
python-version: "3.12"
64-
cache: 'pip'
65-
66-
- name: Install librsvg
67-
run: brew install librsvg
6824

6925
- name: Install uv
7026
run: |
7127
pip install uv
7228
73-
- name: Create virtual env
29+
- name: Install dependencies and build
7430
run: |
7531
uv venv
76-
77-
- name: Install dependencies
78-
run: |
7932
uv sync
33+
uv build
8034
81-
- name: Build macOS installer
82-
run: |
83-
make installer-mac
84-
xattr -dr com.apple.quarantine "installer/build/Basic Memory Installer.app"
85-
86-
- name: Zip macOS installer
35+
- name: Verify version matches tag
8736
run: |
88-
cd installer/build
89-
zip -ry "Basic-Memory-Installer-${{ needs.release.outputs.tag }}.zip" "Basic Memory Installer.app"
90-
91-
- name: Upload macOS installer
92-
uses: softprops/action-gh-release@v1
37+
# Get version from built package
38+
PACKAGE_VERSION=$(uv run python -c "import basic_memory; print(basic_memory.__version__)")
39+
TAG_VERSION=${GITHUB_REF_NAME#v} # Remove 'v' prefix from tag
40+
echo "Package version: $PACKAGE_VERSION"
41+
echo "Tag version: $TAG_VERSION"
42+
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
43+
echo "Version mismatch! Package: $PACKAGE_VERSION, Tag: $TAG_VERSION"
44+
exit 1
45+
fi
46+
47+
- name: Create GitHub Release
48+
uses: softprops/action-gh-release@v2
9349
with:
94-
files: installer/build/Basic-Memory-Installer-${{ needs.release.outputs.tag }}.zip
95-
tag_name: ${{ needs.release.outputs.tag }}
50+
files: |
51+
dist/*.whl
52+
dist/*.tar.gz
53+
generate_release_notes: true
54+
tag_name: ${{ github.ref_name }}
9655
token: ${{ secrets.GITHUB_TOKEN }}
56+
57+
- name: Publish to PyPI
58+
uses: pypa/gh-action-pypi-publish@release/v1
59+
with:
60+
password: ${{ secrets.PYPI_TOKEN }}

.mcp.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"mcpServers": {
3+
"basic-memory": {
4+
"command": "uv",
5+
"args": [
6+
"--directory",
7+
"/Users/phernandez/dev/basicmachines/basic-memory",
8+
"run",
9+
"src/basic_memory/cli/main.py",
10+
"mcp"
11+
]
12+
}
13+
}
14+
}

CLAUDE.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,38 @@ Basic Memory Pro is a desktop GUI application that wraps the basic-memory CLI/MC
187187
- Multiple project support with visual switching interface
188188

189189
local repo: /Users/phernandez/dev/basicmachines/basic-memory-pro
190-
github: https://github.com/basicmachines-co/basic-memory-pro
190+
github: https://github.com/basicmachines-co/basic-memory-pro
191+
192+
## Release and Version Management
193+
194+
Basic Memory uses `uv-dynamic-versioning` for automatic version management based on git tags:
195+
196+
### Version Types
197+
- **Development versions**: Automatically generated from commits (e.g., `0.12.4.dev26+468a22f`)
198+
- **Beta releases**: Created by tagging with beta suffixes (e.g., `v0.13.0b1`, `v0.13.0rc1`)
199+
- **Stable releases**: Created by tagging with version numbers (e.g., `v0.13.0`)
200+
201+
### Release Workflows
202+
203+
#### Development Builds (Automatic)
204+
- Triggered on every push to `main` branch
205+
- Publishes dev versions like `0.12.4.dev26+468a22f` to PyPI
206+
- Allows continuous testing of latest changes
207+
- Users install with: `pip install basic-memory --pre --force-reinstall`
208+
209+
#### Beta/RC Releases (Manual)
210+
- Create beta tag: `git tag v0.13.0b1 && git push origin v0.13.0b1`
211+
- Automatically builds and publishes to PyPI as pre-release
212+
- Users install with: `pip install basic-memory --pre`
213+
- Use for milestone testing before stable release
214+
215+
#### Stable Releases (Manual)
216+
- Create version tag: `git tag v0.13.0 && git push origin v0.13.0`
217+
- Automatically builds, creates GitHub release, and publishes to PyPI
218+
- Users install with: `pip install basic-memory`
219+
220+
### For Development
221+
- No manual version bumping required
222+
- Versions automatically derived from git tags
223+
- `pyproject.toml` uses `dynamic = ["version"]`
224+
- `__init__.py` dynamically reads version from package metadata

CONTRIBUTING.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,40 @@ agreement to the DCO.
144144
- **Database Testing**: Use in-memory SQLite for testing database operations
145145
- **Fixtures**: Use async pytest fixtures for setup and teardown
146146

147+
## Release Process
148+
149+
Basic Memory uses automatic versioning based on git tags with `uv-dynamic-versioning`. Here's how releases work:
150+
151+
### Version Management
152+
- **Development versions**: Automatically generated from git commits (e.g., `0.12.4.dev26+468a22f`)
153+
- **Beta releases**: Created by tagging with beta suffixes (e.g., `git tag v0.13.0b1`)
154+
- **Stable releases**: Created by tagging with version numbers (e.g., `git tag v0.13.0`)
155+
156+
### Release Workflows
157+
158+
#### Development Builds
159+
- Automatically published to PyPI on every commit to `main`
160+
- Version format: `0.12.4.dev26+468a22f` (base version + dev + commit count + hash)
161+
- Users install with: `pip install basic-memory --pre --force-reinstall`
162+
163+
#### Beta Releases
164+
1. Create and push a beta tag: `git tag v0.13.0b1 && git push origin v0.13.0b1`
165+
2. GitHub Actions automatically builds and publishes to PyPI
166+
3. Users install with: `pip install basic-memory --pre`
167+
168+
#### Stable Releases
169+
1. Create and push a version tag: `git tag v0.13.0 && git push origin v0.13.0`
170+
2. GitHub Actions automatically:
171+
- Builds the package with version `0.13.0`
172+
- Creates GitHub release with auto-generated notes
173+
- Publishes to PyPI
174+
3. Users install with: `pip install basic-memory`
175+
176+
### For Contributors
177+
- No manual version bumping required
178+
- Versions are automatically derived from git tags
179+
- Focus on code changes, not version management
180+
147181
## Creating Issues
148182

149183
If you're planning to work on something, please create an issue first to discuss the approach. Include:

EDIT_NOTE.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Looking at write_note, I can see it's a complete content replacement tool. An edit_note() tool would be really valuable for incremental changes. Here's my thinking:
2+
3+
Use Cases for edit_note():
4+
5+
- Append new sections to existing notes (most common)
6+
- Update specific information without rewriting everything
7+
- Add observations/relations to existing content
8+
- Fix typos or update facts
9+
- Prepend updates like meeting notes with timestamps
10+
11+
Proposed Design:
12+
13+
@mcp.tool()
14+
async def edit_note(
15+
identifier: str, # title, permalink, or memory:// URL
16+
operation: str, # "append", "prepend", "replace_section", "find_replace"
17+
content: str, # content to add/replace
18+
section: str = None, # for replace_section - header name like "## Notes"
19+
find_text: str = None, # for find_replace
20+
) -> str:
21+
22+
Operations:
23+
24+
1. append - Add content to end (most useful)
25+
edit_note("project-planning", "append", "\n## New Requirements\n- Feature X\n- Feature Y")
26+
2. prepend - Add content to beginning
27+
edit_note("meeting-notes", "prepend", "## 2025-05-25 Update\n- Progress on feature...")
28+
3. replace_section - Replace content under specific header
29+
edit_note("specs/api", "replace_section", "New API design...", section="## Implementation")
30+
4. find_replace - Simple text replacement
31+
edit_note("config", "find_replace", "v0.13.0", find_text="v0.12.0")
32+
33+
Implementation Flow:
34+
35+
1. Use read_note() internally to get current content
36+
2. Apply the specified operation
37+
3. Use existing PUT /knowledge/entities/{permalink} endpoint
38+
4. Return similar summary as write_note()
39+
40+
This would be perfect for AI assistants making targeted updates without having to regenerate entire documents. The append operation alone would handle 80% of use cases.
41+
42+
Want me to implement this? I'd start with just append and prepend for v0.13.0 to keep it simple.

0 commit comments

Comments
 (0)