Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
321471f
update CLAUDE.md
phernandez Apr 17, 2025
b3af6aa
Merge branch 'main' of github.com:basicmachines-co/basic-memory
phernandez Apr 17, 2025
71941c3
Merge branch 'main' of github.com:basicmachines-co/basic-memory
phernandez May 25, 2025
0daa5b5
feat: add list_directory() tool
phernandez May 25, 2025
6057126
fix: change list_directory path display in results to not include lea…
phernandez May 25, 2025
da5904e
add edit_note tool
phernandez May 26, 2025
279ba07
format and typecheck
phernandez May 26, 2025
7dfd7c5
add project management tools
phernandez May 26, 2025
a664127
add project args for mcp tools
phernandez May 27, 2025
ac1b67d
fix tests and format code
phernandez May 27, 2025
9fb931c
feat: add move note tool
phernandez May 28, 2025
44c116c
add mcp integration tests WIP
phernandez May 28, 2025
23d3428
Merge branch 'main' of github.com:basicmachines-co/basic-memory
phernandez May 28, 2025
af08e5f
Merge branch 'main' into v0.13.0-pre
phernandez May 28, 2025
2dc7e27
fix: Remove # prefix from YAML tags in write_note tool
phernandez May 28, 2025
02dd91a
fix: Make --project flag work consistently across CLI commands
phernandez May 28, 2025
5a11b6e
docs: Mark issue #107 as already resolved
phernandez May 28, 2025
3f5368e
feat: implement frontmatter tag search and fix failing tests
phernandez May 30, 2025
6b6fd76
fix: respect custom permalinks in frontmatter for write_note (#93)
phernandez May 30, 2025
cf9af06
update issues
phernandez May 30, 2025
d4a08d5
update release notes
phernandez May 30, 2025
9cf767f
add mcp int tests
phernandez May 31, 2025
7371387
mcp client integration tests
phernandez May 31, 2025
468a22f
feat: complete comprehensive MCP tools integration testing
phernandez Jun 1, 2025
c834b33
update release flow, add docs for v0.13.0
phernandez Jun 1, 2025
5f8d945
add mcp install and TESTING.md
phernandez Jun 1, 2025
6fc3904
add create_project/delete_project tools
phernandez Jun 2, 2025
1c5a9fc
fix tests
phernandez Jun 3, 2025
5c73adb
fix type-check
phernandez Jun 3, 2025
9371b53
fix test coverage
phernandez Jun 3, 2025
993e88a
re-enable sync test that was skipped
phernandez Jun 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/dev-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Dev Release

on:
push:
branches: [main]
workflow_dispatch: # Allow manual triggering

jobs:
dev-release:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install uv
run: |
pip install uv

- name: Install dependencies and build
run: |
uv venv
uv sync
uv build

- name: Check if this is a dev version
id: check_version
run: |
VERSION=$(uv run python -c "import basic_memory; print(basic_memory.__version__)")
echo "version=$VERSION" >> $GITHUB_OUTPUT
if [[ "$VERSION" == *"dev"* ]]; then
echo "is_dev=true" >> $GITHUB_OUTPUT
echo "Dev version detected: $VERSION"
else
echo "is_dev=false" >> $GITHUB_OUTPUT
echo "Release version detected: $VERSION, skipping dev release"
fi

- name: Publish dev version to PyPI
if: steps.check_version.outputs.is_dev == 'true'
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}
skip-existing: true # Don't fail if version already exists
96 changes: 30 additions & 66 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,96 +1,60 @@
name: Release

on:
workflow_dispatch:
inputs:
version_type:
description: 'Type of version bump (major, minor, patch)'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
push:
tags:
- 'v*' # Trigger on version tags like v1.0.0, v0.13.0, etc.

jobs:
release:
runs-on: ubuntu-latest
concurrency: release
permissions:
id-token: write
contents: write
outputs:
released: ${{ steps.release.outputs.released }}
tag: ${{ steps.release.outputs.tag }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
if: steps.release.outputs.released == 'true'
with:
password: ${{ secrets.PYPI_TOKEN }}

- name: Publish to GitHub Release Assets
uses: python-semantic-release/publish-action@v9.8.9
if: steps.release.outputs.released == 'true'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.release.outputs.tag }}

build-macos:
needs: release
if: needs.release.outputs.released == 'true'
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.tag }}

- name: Set up Python "3.12"
uses: actions/setup-python@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: 'pip'

- name: Install librsvg
run: brew install librsvg

- name: Install uv
run: |
pip install uv

- name: Create virtual env
- name: Install dependencies and build
run: |
uv venv

- name: Install dependencies
run: |
uv sync
uv build

- name: Build macOS installer
run: |
make installer-mac
xattr -dr com.apple.quarantine "installer/build/Basic Memory Installer.app"

- name: Zip macOS installer
- name: Verify version matches tag
run: |
cd installer/build
zip -ry "Basic-Memory-Installer-${{ needs.release.outputs.tag }}.zip" "Basic Memory Installer.app"

- name: Upload macOS installer
uses: softprops/action-gh-release@v1
# Get version from built package
PACKAGE_VERSION=$(uv run python -c "import basic_memory; print(basic_memory.__version__)")
TAG_VERSION=${GITHUB_REF_NAME#v} # Remove 'v' prefix from tag
echo "Package version: $PACKAGE_VERSION"
echo "Tag version: $TAG_VERSION"
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
echo "Version mismatch! Package: $PACKAGE_VERSION, Tag: $TAG_VERSION"
exit 1
fi

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: installer/build/Basic-Memory-Installer-${{ needs.release.outputs.tag }}.zip
tag_name: ${{ needs.release.outputs.tag }}
files: |
dist/*.whl
dist/*.tar.gz
generate_release_notes: true
tag_name: ${{ github.ref_name }}
token: ${{ secrets.GITHUB_TOKEN }}

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}
14 changes: 14 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"mcpServers": {
"basic-memory": {
"command": "uv",
"args": [
"--directory",
"/Users/phernandez/dev/basicmachines/basic-memory",
"run",
"src/basic_memory/cli/main.py",
"mcp"
]
}
}
}
36 changes: 35 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,38 @@ Basic Memory Pro is a desktop GUI application that wraps the basic-memory CLI/MC
- Multiple project support with visual switching interface

local repo: /Users/phernandez/dev/basicmachines/basic-memory-pro
github: https://github.com/basicmachines-co/basic-memory-pro
github: https://github.com/basicmachines-co/basic-memory-pro

## Release and Version Management

Basic Memory uses `uv-dynamic-versioning` for automatic version management based on git tags:

### Version Types
- **Development versions**: Automatically generated from commits (e.g., `0.12.4.dev26+468a22f`)
- **Beta releases**: Created by tagging with beta suffixes (e.g., `v0.13.0b1`, `v0.13.0rc1`)
- **Stable releases**: Created by tagging with version numbers (e.g., `v0.13.0`)

### Release Workflows

#### Development Builds (Automatic)
- Triggered on every push to `main` branch
- Publishes dev versions like `0.12.4.dev26+468a22f` to PyPI
- Allows continuous testing of latest changes
- Users install with: `pip install basic-memory --pre --force-reinstall`

#### Beta/RC Releases (Manual)
- Create beta tag: `git tag v0.13.0b1 && git push origin v0.13.0b1`
- Automatically builds and publishes to PyPI as pre-release
- Users install with: `pip install basic-memory --pre`
- Use for milestone testing before stable release

#### Stable Releases (Manual)
- Create version tag: `git tag v0.13.0 && git push origin v0.13.0`
- Automatically builds, creates GitHub release, and publishes to PyPI
- Users install with: `pip install basic-memory`

### For Development
- No manual version bumping required
- Versions automatically derived from git tags
- `pyproject.toml` uses `dynamic = ["version"]`
- `__init__.py` dynamically reads version from package metadata
34 changes: 34 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,40 @@ agreement to the DCO.
- **Database Testing**: Use in-memory SQLite for testing database operations
- **Fixtures**: Use async pytest fixtures for setup and teardown

## Release Process

Basic Memory uses automatic versioning based on git tags with `uv-dynamic-versioning`. Here's how releases work:

### Version Management
- **Development versions**: Automatically generated from git commits (e.g., `0.12.4.dev26+468a22f`)
- **Beta releases**: Created by tagging with beta suffixes (e.g., `git tag v0.13.0b1`)
- **Stable releases**: Created by tagging with version numbers (e.g., `git tag v0.13.0`)

### Release Workflows

#### Development Builds
- Automatically published to PyPI on every commit to `main`
- Version format: `0.12.4.dev26+468a22f` (base version + dev + commit count + hash)
- Users install with: `pip install basic-memory --pre --force-reinstall`

#### Beta Releases
1. Create and push a beta tag: `git tag v0.13.0b1 && git push origin v0.13.0b1`
2. GitHub Actions automatically builds and publishes to PyPI
3. Users install with: `pip install basic-memory --pre`

#### Stable Releases
1. Create and push a version tag: `git tag v0.13.0 && git push origin v0.13.0`
2. GitHub Actions automatically:
- Builds the package with version `0.13.0`
- Creates GitHub release with auto-generated notes
- Publishes to PyPI
3. Users install with: `pip install basic-memory`

### For Contributors
- No manual version bumping required
- Versions are automatically derived from git tags
- Focus on code changes, not version management

## Creating Issues

If you're planning to work on something, please create an issue first to discuss the approach. Include:
Expand Down
42 changes: 42 additions & 0 deletions EDIT_NOTE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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:

Use Cases for edit_note():

- Append new sections to existing notes (most common)
- Update specific information without rewriting everything
- Add observations/relations to existing content
- Fix typos or update facts
- Prepend updates like meeting notes with timestamps

Proposed Design:

@mcp.tool()
async def edit_note(
identifier: str, # title, permalink, or memory:// URL
operation: str, # "append", "prepend", "replace_section", "find_replace"
content: str, # content to add/replace
section: str = None, # for replace_section - header name like "## Notes"
find_text: str = None, # for find_replace
) -> str:

Operations:

1. append - Add content to end (most useful)
edit_note("project-planning", "append", "\n## New Requirements\n- Feature X\n- Feature Y")
2. prepend - Add content to beginning
edit_note("meeting-notes", "prepend", "## 2025-05-25 Update\n- Progress on feature...")
3. replace_section - Replace content under specific header
edit_note("specs/api", "replace_section", "New API design...", section="## Implementation")
4. find_replace - Simple text replacement
edit_note("config", "find_replace", "v0.13.0", find_text="v0.12.0")

Implementation Flow:

1. Use read_note() internally to get current content
2. Apply the specified operation
3. Use existing PUT /knowledge/entities/{permalink} endpoint
4. Return similar summary as write_note()

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.

Want me to implement this? I'd start with just append and prepend for v0.13.0 to keep it simple.
Loading
Loading