memleaf 0.1.2__tar.gz → 0.1.4__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.
- memleaf-0.1.4/CHANGELOG.md +61 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/MANIFEST.in +1 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/PKG-INFO +37 -39
- {memleaf-0.1.2 → memleaf-0.1.4}/README.en.md +36 -37
- {memleaf-0.1.2 → memleaf-0.1.4}/README.md +35 -36
- memleaf-0.1.4/install.ps1 +88 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/integrations/hermes/memleaf/plugin.yaml +1 -1
- {memleaf-0.1.2 → memleaf-0.1.4}/pyproject.toml +3 -3
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/__init__.py +1 -1
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/adapters/base.py +13 -2
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/adapters/hermes.py +58 -6
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/cli.py +9 -4
- memleaf-0.1.4/src/memleaf/credentials.py +57 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/hermes_provider/plugin.yaml +1 -1
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/installer.py +15 -10
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/router.py +5 -4
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/locking.py +4 -1
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/model_discovery.py +32 -15
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf.egg-info/PKG-INFO +37 -39
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf.egg-info/SOURCES.txt +3 -1
- memleaf-0.1.4/tests/test_credential_safety.py +98 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_model_discovery.py +102 -0
- memleaf-0.1.4/tests/test_pypi_install.py +112 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_c1_mcp.py +1 -1
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_c3_packaging.py +3 -3
- memleaf-0.1.2/CHANGELOG.md +0 -54
- memleaf-0.1.2/LICENSE +0 -235
- memleaf-0.1.2/tests/test_pypi_install.py +0 -52
- {memleaf-0.1.2 → memleaf-0.1.4}/IMPLEMENTATION_PLAN.md +0 -0
- /memleaf-0.1.2/LICENSES/MIT-0.1.0-0.1.1.txt → /memleaf-0.1.4/LICENSE +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/RELEASE_CHECKLIST.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/RELEASE_NOTES_v0.1.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/V2_IMPLEMENTATION_PLAN.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/examples/README.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/examples/basic_usage.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/examples/mcp_stdio.ndjson +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/install.sh +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/integrations/hermes/memleaf/README.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/integrations/hermes/memleaf/__init__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/setup.cfg +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/__main__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/adapters/__init__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/adapters/antigravity.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/adapters/codex.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/budget.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/capture.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/compaction.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/config.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/frontmatter.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/hermes_provider/README.md +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/hermes_provider/__init__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/host_events.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/inbox.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/index.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/__init__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/base.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/claude_compatible.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/gemini.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/llm/openai_compatible.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/mcp_server.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/memory_writer.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/models.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/native_index.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/processing.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/prompts.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/redaction.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/retrieval.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/retrieval_gate.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/scope_maintenance.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/scope_state.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/service.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/validation.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf/vault.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf.egg-info/dependency_links.txt +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf.egg-info/entry_points.txt +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/src/memleaf.egg-info/top_level.txt +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/__init__.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_admission_noise.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_context_budget.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_hermes_provider.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_host_events.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_install.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_maintenance_v2.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_retrieval_gate.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_retrieval_v2.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_a.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b1.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b2a.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b2b.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3a_commit.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3a_contract.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3b_native_context.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3b_native_index.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3b_scope.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3c_retrieval.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_b3d_scope_maintenance.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_stage_c2_init.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_v2_gate_limits.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_v2_host_flow.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_v2_mcp_flow.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_v2_nomatch_semantics.py +0 -0
- {memleaf-0.1.2 → memleaf-0.1.4}/tests/test_v2_search_gate_acceptance.py +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to memleaf are documented here.
|
|
4
|
+
|
|
5
|
+
## 0.1.4 — 2026-08-28
|
|
6
|
+
|
|
7
|
+
- Reject Hermes display-redacted API credentials such as `***` and head/tail masks instead of treating them as callable keys.
|
|
8
|
+
- Fall through from a redacted direct credential to configured environment variables and Hermes `.env` values.
|
|
9
|
+
- Reject masked credentials in existing memleaf routes and at runtime so an old bad route cannot remain silently usable.
|
|
10
|
+
- Add regression coverage for masked Hermes credentials on Linux and Windows.
|
|
11
|
+
|
|
12
|
+
## 0.1.3 — 2026-08-28
|
|
13
|
+
|
|
14
|
+
- Restored the MIT License for the current release.
|
|
15
|
+
- Added native Windows Hermes path discovery using `HERMES_HOME` or the official
|
|
16
|
+
`%LOCALAPPDATA%\hermes` default.
|
|
17
|
+
- Added discovery for the official Windows Hermes launchers under
|
|
18
|
+
`bin\hermes.exe`, `bin\hermes.cmd`, and
|
|
19
|
+
`hermes-agent\venv\Scripts\hermes.exe`.
|
|
20
|
+
- Added a one-line PowerShell installer that uses Hermes' managed Python when
|
|
21
|
+
available, installs memleaf from PyPI, and completes Hermes integration.
|
|
22
|
+
- Made atomic file writes and Windows command-launcher detection portable.
|
|
23
|
+
- Added Windows GitHub Actions coverage for Python 3.11, 3.12, and 3.13.
|
|
24
|
+
|
|
25
|
+
## 0.1.2 — 2026-08-28
|
|
26
|
+
|
|
27
|
+
- This release was published under AGPL-3.0-only before the project returned to
|
|
28
|
+
MIT in 0.1.3. Its original license remains valid for copies of 0.1.2.
|
|
29
|
+
- Product behavior otherwise remained aligned with 0.1.1.
|
|
30
|
+
|
|
31
|
+
## 0.1.1 — 2026-08-28 (GitHub tag: v0.1.1)
|
|
32
|
+
|
|
33
|
+
- Added a first-class `memleaf install` command for complete Hermes setup
|
|
34
|
+
after installing the package from PyPI.
|
|
35
|
+
- Packaged the Hermes MemoryProvider inside the Python distribution, removing
|
|
36
|
+
the need for a Git checkout during normal installation.
|
|
37
|
+
- Added safe migration from the source-installed provider symlink to the
|
|
38
|
+
packaged provider.
|
|
39
|
+
- Added `python -m memleaf` so the complete one-line install works even when
|
|
40
|
+
the console-script directory is not already on PATH.
|
|
41
|
+
- The installer initializes the Vault, discovers or preserves a model route,
|
|
42
|
+
activates the Hermes MemoryProvider, configures MCP lifecycle settings, and
|
|
43
|
+
verifies the 11-tool MCP surface.
|
|
44
|
+
|
|
45
|
+
## 0.1.0 — 2026-08-28 (GitHub tag: v0.1)
|
|
46
|
+
|
|
47
|
+
- Added the local-first, dependency-free Markdown vault core with capture,
|
|
48
|
+
memory creation, deterministic search/context retrieval, statistics, and
|
|
49
|
+
rebuildable indexes.
|
|
50
|
+
- Added safe vault paths, file locking/atomic writes, frontmatter handling, and
|
|
51
|
+
secret redaction for captured text.
|
|
52
|
+
- Added model-backed admission, extraction, state updates with history,
|
|
53
|
+
compaction, retryable processing, and scope-aware maintenance without adding
|
|
54
|
+
runtime dependencies.
|
|
55
|
+
- Added the `memleaf` initialization CLI and the `memleaf-mcp` stdio entry
|
|
56
|
+
point.
|
|
57
|
+
- Added Scope Map → directory search → bounded read retrieval with per-turn
|
|
58
|
+
retrieval state, pagination, and read budgets.
|
|
59
|
+
- Added a Hermes-native MemoryProvider plus MCP setup.
|
|
60
|
+
- Added packaging metadata, examples, offline local installation, and CI for
|
|
61
|
+
Python 3.11–3.13.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memleaf
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A local-first Markdown memory core for AI agents
|
|
5
5
|
Author: memleaf contributors
|
|
6
|
-
License-Expression:
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Keywords: ai-agents,local-first,markdown,memory
|
|
8
8
|
Classifier: Intended Audience :: Developers
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -15,7 +15,6 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
15
15
|
Requires-Python: >=3.11
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
License-File: LICENSES/MIT-0.1.0-0.1.1.txt
|
|
19
18
|
Dynamic: license-file
|
|
20
19
|
|
|
21
20
|
# 冥想盆 · memleaf
|
|
@@ -24,8 +23,8 @@ Dynamic: license-file
|
|
|
24
23
|
|
|
25
24
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
26
25
|
|
|
27
|
-
> **当前版本:0.1.
|
|
28
|
-
> 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。memleaf 0.1.
|
|
26
|
+
> **当前版本:0.1.4。**
|
|
27
|
+
> 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。memleaf 0.1.4 通过 PyPI 分发。
|
|
29
28
|
> **当前版本仅支持 Hermes。** Codex 与反重力不检测、不安装、不配置,也不扫描其模型配置。
|
|
30
29
|
|
|
31
30
|
## 项目定位
|
|
@@ -102,21 +101,40 @@ memleaf 不把每句话都保存为记忆。处理一轮完整的 user + assista
|
|
|
102
101
|
|
|
103
102
|
## 安装
|
|
104
103
|
|
|
105
|
-
|
|
104
|
+
要求 Python 3.11+;当前版本的完整自动接入支持 Hermes。
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
### Windows
|
|
107
|
+
|
|
108
|
+
已经安装 Hermes 的 Windows 10/11 用户,在 **PowerShell** 中只需要执行一行:
|
|
109
|
+
|
|
110
|
+
```powershell
|
|
111
|
+
irm https://raw.githubusercontent.com/miffyblueboo/memleaf/main/install.ps1 | iex
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Windows 安装器会优先使用 Hermes 自带的 Python 环境,因此不要求 Hermes 的 Python 已加入系统 PATH。它会从 PyPI 安装或升级 memleaf,然后自动完成 Hermes 接入。
|
|
115
|
+
|
|
116
|
+
默认情况下会识别 Hermes 官方 Windows 安装位置:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
%USERPROFILE%\.memleaf\ # memleaf 数据 Vault
|
|
120
|
+
%LOCALAPPDATA%\hermes\plugins\memleaf\ # Hermes MemoryProvider
|
|
121
|
+
%LOCALAPPDATA%\hermes\memleaf.json # Provider 配置
|
|
122
|
+
%LOCALAPPDATA%\hermes\bin\hermes.exe / hermes.cmd # Hermes 命令入口
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
如果设置了 `HERMES_HOME`,memleaf 会优先使用该目录。
|
|
126
|
+
|
|
127
|
+
### macOS / Linux
|
|
108
128
|
|
|
109
129
|
```bash
|
|
110
130
|
python -m pip install -U memleaf && python -m memleaf install
|
|
111
131
|
```
|
|
112
132
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`memleaf install` 会自动:
|
|
133
|
+
两种安装方式最终都会自动:
|
|
116
134
|
|
|
117
|
-
1. 初始化默认 Vault
|
|
118
|
-
2.
|
|
119
|
-
3.
|
|
135
|
+
1. 初始化默认 Vault;
|
|
136
|
+
2. 安装或升级 Hermes MemoryProvider;
|
|
137
|
+
3. 发现并保存可用的聊天模型路由;Hermes CLI 返回的脱敏凭证不会被当成真实 API key,而会继续尝试环境变量和 Hermes `.env`;已有有效 memleaf 路由会保留;
|
|
120
138
|
4. 激活 `memory.provider=memleaf`;
|
|
121
139
|
5. 通过 Hermes 官方 CLI 配置 memleaf MCP;
|
|
122
140
|
6. 配置 MCP lazy/idle 生命周期;
|
|
@@ -125,25 +143,9 @@ python -m pip install -U memleaf && python -m memleaf install
|
|
|
125
143
|
|
|
126
144
|
完成后重启 Hermes。
|
|
127
145
|
|
|
128
|
-
|
|
146
|
+
如果没有检测到 Hermes、无法取得完整模型路由、Provider 激活失败或 MCP 的 11 工具验证失败,安装会明确返回失败,不会把未完成的接入报告为成功。
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
$HOME/.memleaf/ # memleaf 数据 Vault
|
|
132
|
-
$HERMES_HOME/plugins/memleaf/ # Hermes MemoryProvider
|
|
133
|
-
$HERMES_HOME/memleaf.json # Provider 的 Vault、MCP 命令和超时配置
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
Python 包和 `memleaf` / `memleaf-mcp` 命令由当前 Python/pip 环境管理,不再要求固定的 `$HOME/memleaf` 源码目录。
|
|
137
|
-
|
|
138
|
-
如需自定义 Vault,也仍是一行:
|
|
139
|
-
|
|
140
|
-
```bash
|
|
141
|
-
python -m pip install -U memleaf && python -m memleaf install --vault /path/to/vault
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
如果没有检测到 Hermes 可执行文件、无法取得完整模型路由、Provider 激活失败或 MCP 的 11 工具验证失败,安装命令会明确返回失败,不会把未完成的接入报告为成功。
|
|
145
|
-
|
|
146
|
-
仓库中的 `install.sh` 继续保留给源码开发、离线源码安装和故障排查;**普通 PyPI 用户不需要执行它**。
|
|
148
|
+
仓库中的 `install.sh` 保留给源码开发、离线源码安装和故障排查;普通 PyPI 用户不需要执行它。
|
|
147
149
|
|
|
148
150
|
Codex 和 Antigravity(反重力)当前暂不支持:安装流程不会检测、安装或修改它们的 MCP、Hook 或模型配置。
|
|
149
151
|
|
|
@@ -290,7 +292,7 @@ python -m memleaf.mcp_server --vault /path/to/your/vault \
|
|
|
290
292
|
- `host`:只使用 Python API 显式传入的宿主回调;
|
|
291
293
|
- `api`:只使用本地配置的 HTTP API。
|
|
292
294
|
|
|
293
|
-
`memleaf init`
|
|
295
|
+
`memleaf init` 从 Hermes 的可读取模型配置中寻找完整的聊天模型路由,过滤非聊天模型,并确定性选择轻量模型作为提炼模型。Hermes CLI 输出中的 `***`、`sk-p...7890` 等显示脱敏值会被视为缺失凭证,并继续尝试环境变量或 Hermes `.env`;若仍找不到真实凭证则安装明确失败,不会写入一个看似成功但不可调用的模型路由。未发现可用路由时复用已有的有效 memleaf 配置;要保留自选路由并跳过扫描,使用 `--no-model-discovery`。不能调用的 OAuth-only 或只有模型名的配置不会被误判为可用。
|
|
294
296
|
|
|
295
297
|
API 配置示例:
|
|
296
298
|
|
|
@@ -385,7 +387,7 @@ python3.11 -m compileall -q src tests examples
|
|
|
385
387
|
git diff --check
|
|
386
388
|
```
|
|
387
389
|
|
|
388
|
-
GitHub Actions
|
|
390
|
+
GitHub Actions 覆盖 Linux 与 Windows 的 Python 3.11、3.12、3.13 测试,并验证 wheel/source distribution 构建、源码包测试和 Windows PowerShell 安装器语法。构建发行包需要 `build`:
|
|
389
391
|
|
|
390
392
|
```bash
|
|
391
393
|
python -m pip install build
|
|
@@ -397,7 +399,7 @@ python -m build --wheel --sdist
|
|
|
397
399
|
|
|
398
400
|
以下内容不应被 README 或安装结果误解为已交付能力:
|
|
399
401
|
|
|
400
|
-
-
|
|
402
|
+
- Windows、macOS 和 Linux 都提供一行安装入口完成 Hermes 自动接入;源码 `install.sh` 仅保留给开发、离线源码安装和故障排查;
|
|
401
403
|
- 当前仅支持 Hermes;Codex 和 Antigravity(反重力)不检测、不安装、不配置;
|
|
402
404
|
- Hermes 的检索门控是 Soft Gate,不保证阻止所有未检索回答;
|
|
403
405
|
- 没有模型路由时只能捕获和检索,不能完成自动提炼、显式记忆或压缩;
|
|
@@ -408,11 +410,7 @@ python -m build --wheel --sdist
|
|
|
408
410
|
|
|
409
411
|
## License
|
|
410
412
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
AGPL 允许个人和商业使用,但修改、分发或通过网络提供受 AGPL 覆盖的版本时,需要遵守相应的源代码开放义务。希望在闭源商业产品或专有服务中使用 memleaf、且不希望受 AGPL 条款约束的企业,可以申请单独的商业授权,见 [COMMERCIAL_LICENSE.md](COMMERCIAL_LICENSE.md)。
|
|
414
|
-
|
|
415
|
-
0.1.0 和 0.1.1 已经按 MIT License 发布,既有 MIT 授权继续有效。历史许可证见 [LICENSES/MIT-0.1.0-0.1.1.txt](LICENSES/MIT-0.1.0-0.1.1.txt)。
|
|
413
|
+
MIT,见 [LICENSE](LICENSE)。
|
|
416
414
|
|
|
417
415
|
**memleaf**
|
|
418
416
|
*Your memories, in files you own.*
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
[中文](README.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **Version: 0.1.
|
|
8
|
-
> The core library, Vault, stdio MCP server, initialization CLI, model routing, memory extraction, controlled retrieval protocol, and host adapters are implemented. memleaf 0.1.
|
|
7
|
+
> **Version: 0.1.4.**
|
|
8
|
+
> The core library, Vault, stdio MCP server, initialization CLI, model routing, memory extraction, controlled retrieval protocol, and host adapters are implemented. memleaf 0.1.4 is distributed through PyPI.
|
|
9
9
|
> **The current release supports only Hermes.** Codex and Antigravity are not detected, installed, configured, or scanned for models.
|
|
10
10
|
|
|
11
11
|
## Project scope
|
|
@@ -82,48 +82,51 @@ Additional rules:
|
|
|
82
82
|
|
|
83
83
|
## Installation
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
Python 3.11+ is required. Full automatic host setup currently supports Hermes.
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
### Windows
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
python -m pip install -U memleaf && python -m memleaf install
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
That one line first installs or upgrades memleaf from PyPI and then immediately performs the complete Hermes integration. Users do not need to `git clone`, `cd`, or run `install.sh`.
|
|
89
|
+
If Hermes is already installed on Windows 10/11, run this single line in **PowerShell**:
|
|
94
90
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
2. Installs or upgrades the packaged Hermes MemoryProvider at `$HERMES_HOME/plugins/memleaf`.
|
|
99
|
-
3. Discovers and saves a callable chat-model route while preserving an existing valid memleaf route.
|
|
100
|
-
4. Activates `memory.provider=memleaf`.
|
|
101
|
-
5. Configures the memleaf MCP entry through Hermes' official CLI.
|
|
102
|
-
6. Configures MCP lazy/idle lifecycle settings.
|
|
103
|
-
7. Verifies that the MCP server exposes all 11 tools.
|
|
104
|
-
8. Records the local Agent integration status.
|
|
91
|
+
```powershell
|
|
92
|
+
irm https://raw.githubusercontent.com/miffyblueboo/memleaf/main/install.ps1 | iex
|
|
93
|
+
```
|
|
105
94
|
|
|
106
|
-
|
|
95
|
+
The Windows installer prefers Hermes' managed Python environment, so Hermes' Python does not need to be on the system PATH. It installs or upgrades memleaf from PyPI and then completes the Hermes integration automatically.
|
|
107
96
|
|
|
108
|
-
|
|
97
|
+
The official native Windows Hermes locations are detected by default:
|
|
109
98
|
|
|
110
99
|
```text
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
100
|
+
%USERPROFILE%\.memleaf\ # memleaf data Vault
|
|
101
|
+
%LOCALAPPDATA%\hermes\plugins\memleaf\ # Hermes MemoryProvider
|
|
102
|
+
%LOCALAPPDATA%\hermes\memleaf.json # Provider configuration
|
|
103
|
+
%LOCALAPPDATA%\hermes\bin\hermes.exe / hermes.cmd # Hermes launcher
|
|
114
104
|
```
|
|
115
105
|
|
|
116
|
-
|
|
106
|
+
If `HERMES_HOME` is set, memleaf uses it instead.
|
|
117
107
|
|
|
118
|
-
|
|
108
|
+
### macOS / Linux
|
|
119
109
|
|
|
120
110
|
```bash
|
|
121
|
-
python -m pip install -U memleaf && python -m memleaf install
|
|
111
|
+
python -m pip install -U memleaf && python -m memleaf install
|
|
122
112
|
```
|
|
123
113
|
|
|
124
|
-
|
|
114
|
+
Both installation paths automatically:
|
|
115
|
+
|
|
116
|
+
1. Initialize the default Vault.
|
|
117
|
+
2. Install or upgrade the Hermes MemoryProvider.
|
|
118
|
+
3. Discover and save a callable chat-model route. Redacted credentials returned by the Hermes CLI are never treated as real API keys; discovery falls through to environment variables and Hermes `.env`, while preserving an existing valid memleaf route.
|
|
119
|
+
4. Activate `memory.provider=memleaf`.
|
|
120
|
+
5. Configure the memleaf MCP entry through Hermes' official CLI.
|
|
121
|
+
6. Configure MCP lazy/idle lifecycle settings.
|
|
122
|
+
7. Verify that the MCP server exposes all 11 tools.
|
|
123
|
+
8. Record the local Agent integration status.
|
|
124
|
+
|
|
125
|
+
Restart Hermes after installation.
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
If Hermes cannot be detected, no complete model route can be configured, Provider activation fails, or the 11-tool MCP verification fails, the installer returns an explicit failure rather than reporting an incomplete integration as successful.
|
|
128
|
+
|
|
129
|
+
The repository `install.sh` remains for source development, offline source installation, and troubleshooting. Normal PyPI users do not need to run it.
|
|
127
130
|
|
|
128
131
|
Codex and Antigravity are not currently supported. The install flow does not detect, install, or modify their MCP, hook, or model configuration.
|
|
129
132
|
|
|
@@ -270,7 +273,7 @@ Capture, indexing, directory retrieval, and reading work offline. `process()`, `
|
|
|
270
273
|
- `host`: use only a host callback explicitly supplied to the Python API;
|
|
271
274
|
- `api`: use only the locally configured HTTP API.
|
|
272
275
|
|
|
273
|
-
`memleaf init` looks for complete chat-model routes
|
|
276
|
+
`memleaf init` looks for complete chat-model routes in readable Hermes model configuration, filters out non-chat models, and deterministically selects a lightweight model for extraction. Display-redacted values such as `***` or `sk-p...7890` are treated as missing credentials; discovery then tries environment variables and Hermes `.env`, and fails explicitly if no real credential is available instead of writing a false-success route. An existing valid memleaf route is reused when discovery finds none; use `--no-model-discovery` to preserve a custom route without scanning. OAuth-only routes and model names without a callable route are not treated as usable.
|
|
274
277
|
|
|
275
278
|
API configuration example:
|
|
276
279
|
|
|
@@ -365,7 +368,7 @@ python3.11 -m compileall -q src tests examples
|
|
|
365
368
|
git diff --check
|
|
366
369
|
```
|
|
367
370
|
|
|
368
|
-
GitHub Actions
|
|
371
|
+
GitHub Actions covers Python 3.11, 3.12, and 3.13 on Linux and Windows, plus wheel/source-distribution builds, source-archive tests, and PowerShell installer syntax validation. Build packages with:
|
|
369
372
|
|
|
370
373
|
```bash
|
|
371
374
|
python -m pip install build
|
|
@@ -377,7 +380,7 @@ python -m build --wheel --sdist
|
|
|
377
380
|
|
|
378
381
|
The following should not be interpreted as delivered capabilities:
|
|
379
382
|
|
|
380
|
-
-
|
|
383
|
+
- Windows, macOS, and Linux each provide a one-line Hermes integration entry point; the source `install.sh` remains only for development, offline source installation, and troubleshooting.
|
|
381
384
|
- The current release supports only Hermes. Codex and Antigravity are not detected, installed, or configured.
|
|
382
385
|
- Hermes retrieval gating is a Soft Gate and does not guarantee that every answer performed retrieval.
|
|
383
386
|
- Without a model route, memleaf can capture and retrieve but cannot perform automatic extraction, explicit model-backed memory, or compaction.
|
|
@@ -388,11 +391,7 @@ The following should not be interpreted as delivered capabilities:
|
|
|
388
391
|
|
|
389
392
|
## License
|
|
390
393
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
The AGPL permits both personal and commercial use, subject to its source-code obligations for covered modification, distribution, and network use. Organizations that need to use memleaf in proprietary products or services without the AGPL obligations can obtain a separate commercial license; see [COMMERCIAL_LICENSE.md](COMMERCIAL_LICENSE.md).
|
|
394
|
-
|
|
395
|
-
Versions 0.1.0 and 0.1.1 were released under the MIT License, and the rights already granted for those releases remain in effect. See [LICENSES/MIT-0.1.0-0.1.1.txt](LICENSES/MIT-0.1.0-0.1.1.txt).
|
|
394
|
+
MIT; see [LICENSE](LICENSE).
|
|
396
395
|
|
|
397
396
|
**memleaf**
|
|
398
397
|
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **当前版本:0.1.
|
|
8
|
-
> 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。memleaf 0.1.
|
|
7
|
+
> **当前版本:0.1.4。**
|
|
8
|
+
> 核心库、Vault、stdio MCP Server、初始化 CLI、模型路由、提炼流程、受控检索协议和宿主适配器已经实现。memleaf 0.1.4 通过 PyPI 分发。
|
|
9
9
|
> **当前版本仅支持 Hermes。** Codex 与反重力不检测、不安装、不配置,也不扫描其模型配置。
|
|
10
10
|
|
|
11
11
|
## 项目定位
|
|
@@ -82,21 +82,40 @@ memleaf 不把每句话都保存为记忆。处理一轮完整的 user + assista
|
|
|
82
82
|
|
|
83
83
|
## 安装
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
要求 Python 3.11+;当前版本的完整自动接入支持 Hermes。
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
### Windows
|
|
88
|
+
|
|
89
|
+
已经安装 Hermes 的 Windows 10/11 用户,在 **PowerShell** 中只需要执行一行:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
irm https://raw.githubusercontent.com/miffyblueboo/memleaf/main/install.ps1 | iex
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Windows 安装器会优先使用 Hermes 自带的 Python 环境,因此不要求 Hermes 的 Python 已加入系统 PATH。它会从 PyPI 安装或升级 memleaf,然后自动完成 Hermes 接入。
|
|
96
|
+
|
|
97
|
+
默认情况下会识别 Hermes 官方 Windows 安装位置:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
%USERPROFILE%\.memleaf\ # memleaf 数据 Vault
|
|
101
|
+
%LOCALAPPDATA%\hermes\plugins\memleaf\ # Hermes MemoryProvider
|
|
102
|
+
%LOCALAPPDATA%\hermes\memleaf.json # Provider 配置
|
|
103
|
+
%LOCALAPPDATA%\hermes\bin\hermes.exe / hermes.cmd # Hermes 命令入口
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
如果设置了 `HERMES_HOME`,memleaf 会优先使用该目录。
|
|
107
|
+
|
|
108
|
+
### macOS / Linux
|
|
88
109
|
|
|
89
110
|
```bash
|
|
90
111
|
python -m pip install -U memleaf && python -m memleaf install
|
|
91
112
|
```
|
|
92
113
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`memleaf install` 会自动:
|
|
114
|
+
两种安装方式最终都会自动:
|
|
96
115
|
|
|
97
|
-
1. 初始化默认 Vault
|
|
98
|
-
2.
|
|
99
|
-
3.
|
|
116
|
+
1. 初始化默认 Vault;
|
|
117
|
+
2. 安装或升级 Hermes MemoryProvider;
|
|
118
|
+
3. 发现并保存可用的聊天模型路由;Hermes CLI 返回的脱敏凭证不会被当成真实 API key,而会继续尝试环境变量和 Hermes `.env`;已有有效 memleaf 路由会保留;
|
|
100
119
|
4. 激活 `memory.provider=memleaf`;
|
|
101
120
|
5. 通过 Hermes 官方 CLI 配置 memleaf MCP;
|
|
102
121
|
6. 配置 MCP lazy/idle 生命周期;
|
|
@@ -105,25 +124,9 @@ python -m pip install -U memleaf && python -m memleaf install
|
|
|
105
124
|
|
|
106
125
|
完成后重启 Hermes。
|
|
107
126
|
|
|
108
|
-
|
|
127
|
+
如果没有检测到 Hermes、无法取得完整模型路由、Provider 激活失败或 MCP 的 11 工具验证失败,安装会明确返回失败,不会把未完成的接入报告为成功。
|
|
109
128
|
|
|
110
|
-
|
|
111
|
-
$HOME/.memleaf/ # memleaf 数据 Vault
|
|
112
|
-
$HERMES_HOME/plugins/memleaf/ # Hermes MemoryProvider
|
|
113
|
-
$HERMES_HOME/memleaf.json # Provider 的 Vault、MCP 命令和超时配置
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Python 包和 `memleaf` / `memleaf-mcp` 命令由当前 Python/pip 环境管理,不再要求固定的 `$HOME/memleaf` 源码目录。
|
|
117
|
-
|
|
118
|
-
如需自定义 Vault,也仍是一行:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
python -m pip install -U memleaf && python -m memleaf install --vault /path/to/vault
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
如果没有检测到 Hermes 可执行文件、无法取得完整模型路由、Provider 激活失败或 MCP 的 11 工具验证失败,安装命令会明确返回失败,不会把未完成的接入报告为成功。
|
|
125
|
-
|
|
126
|
-
仓库中的 `install.sh` 继续保留给源码开发、离线源码安装和故障排查;**普通 PyPI 用户不需要执行它**。
|
|
129
|
+
仓库中的 `install.sh` 保留给源码开发、离线源码安装和故障排查;普通 PyPI 用户不需要执行它。
|
|
127
130
|
|
|
128
131
|
Codex 和 Antigravity(反重力)当前暂不支持:安装流程不会检测、安装或修改它们的 MCP、Hook 或模型配置。
|
|
129
132
|
|
|
@@ -270,7 +273,7 @@ python -m memleaf.mcp_server --vault /path/to/your/vault \
|
|
|
270
273
|
- `host`:只使用 Python API 显式传入的宿主回调;
|
|
271
274
|
- `api`:只使用本地配置的 HTTP API。
|
|
272
275
|
|
|
273
|
-
`memleaf init`
|
|
276
|
+
`memleaf init` 从 Hermes 的可读取模型配置中寻找完整的聊天模型路由,过滤非聊天模型,并确定性选择轻量模型作为提炼模型。Hermes CLI 输出中的 `***`、`sk-p...7890` 等显示脱敏值会被视为缺失凭证,并继续尝试环境变量或 Hermes `.env`;若仍找不到真实凭证则安装明确失败,不会写入一个看似成功但不可调用的模型路由。未发现可用路由时复用已有的有效 memleaf 配置;要保留自选路由并跳过扫描,使用 `--no-model-discovery`。不能调用的 OAuth-only 或只有模型名的配置不会被误判为可用。
|
|
274
277
|
|
|
275
278
|
API 配置示例:
|
|
276
279
|
|
|
@@ -365,7 +368,7 @@ python3.11 -m compileall -q src tests examples
|
|
|
365
368
|
git diff --check
|
|
366
369
|
```
|
|
367
370
|
|
|
368
|
-
GitHub Actions
|
|
371
|
+
GitHub Actions 覆盖 Linux 与 Windows 的 Python 3.11、3.12、3.13 测试,并验证 wheel/source distribution 构建、源码包测试和 Windows PowerShell 安装器语法。构建发行包需要 `build`:
|
|
369
372
|
|
|
370
373
|
```bash
|
|
371
374
|
python -m pip install build
|
|
@@ -377,7 +380,7 @@ python -m build --wheel --sdist
|
|
|
377
380
|
|
|
378
381
|
以下内容不应被 README 或安装结果误解为已交付能力:
|
|
379
382
|
|
|
380
|
-
-
|
|
383
|
+
- Windows、macOS 和 Linux 都提供一行安装入口完成 Hermes 自动接入;源码 `install.sh` 仅保留给开发、离线源码安装和故障排查;
|
|
381
384
|
- 当前仅支持 Hermes;Codex 和 Antigravity(反重力)不检测、不安装、不配置;
|
|
382
385
|
- Hermes 的检索门控是 Soft Gate,不保证阻止所有未检索回答;
|
|
383
386
|
- 没有模型路由时只能捕获和检索,不能完成自动提炼、显式记忆或压缩;
|
|
@@ -388,11 +391,7 @@ python -m build --wheel --sdist
|
|
|
388
391
|
|
|
389
392
|
## License
|
|
390
393
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
AGPL 允许个人和商业使用,但修改、分发或通过网络提供受 AGPL 覆盖的版本时,需要遵守相应的源代码开放义务。希望在闭源商业产品或专有服务中使用 memleaf、且不希望受 AGPL 条款约束的企业,可以申请单独的商业授权,见 [COMMERCIAL_LICENSE.md](COMMERCIAL_LICENSE.md)。
|
|
394
|
-
|
|
395
|
-
0.1.0 和 0.1.1 已经按 MIT License 发布,既有 MIT 授权继续有效。历史许可证见 [LICENSES/MIT-0.1.0-0.1.1.txt](LICENSES/MIT-0.1.0-0.1.1.txt)。
|
|
394
|
+
MIT,见 [LICENSE](LICENSE)。
|
|
396
395
|
|
|
397
396
|
**memleaf**
|
|
398
397
|
*Your memories, in files you own.*
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
$ErrorActionPreference = "Stop"
|
|
2
|
+
|
|
3
|
+
function Invoke-MemleafPython {
|
|
4
|
+
param([Parameter(Mandatory = $true)][string[]]$PythonArgs)
|
|
5
|
+
|
|
6
|
+
& $script:MemleafPython @script:MemleafPythonPrefix @PythonArgs
|
|
7
|
+
if ($LASTEXITCODE -ne 0) {
|
|
8
|
+
throw "Python command failed with exit code $LASTEXITCODE"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$hermesHome = $env:HERMES_HOME
|
|
13
|
+
if ([string]::IsNullOrWhiteSpace($hermesHome)) {
|
|
14
|
+
if ([string]::IsNullOrWhiteSpace($env:LOCALAPPDATA)) {
|
|
15
|
+
throw "LOCALAPPDATA is unavailable and HERMES_HOME is not set."
|
|
16
|
+
}
|
|
17
|
+
$hermesHome = Join-Path $env:LOCALAPPDATA "hermes"
|
|
18
|
+
}
|
|
19
|
+
$hermesHome = [System.IO.Path]::GetFullPath($hermesHome)
|
|
20
|
+
|
|
21
|
+
$managedPython = Join-Path $hermesHome "hermes-agent\venv\Scripts\python.exe"
|
|
22
|
+
$script:MemleafPythonPrefix = @()
|
|
23
|
+
|
|
24
|
+
if (Test-Path -LiteralPath $managedPython -PathType Leaf) {
|
|
25
|
+
$script:MemleafPython = $managedPython
|
|
26
|
+
} else {
|
|
27
|
+
$pythonCommand = Get-Command python -ErrorAction SilentlyContinue
|
|
28
|
+
if ($pythonCommand) {
|
|
29
|
+
$script:MemleafPython = $pythonCommand.Source
|
|
30
|
+
} else {
|
|
31
|
+
$pyCommand = Get-Command py -ErrorAction SilentlyContinue
|
|
32
|
+
if ($pyCommand) {
|
|
33
|
+
$script:MemleafPython = $pyCommand.Source
|
|
34
|
+
$script:MemleafPythonPrefix = @("-3.11")
|
|
35
|
+
} else {
|
|
36
|
+
throw "Python 3.11+ was not found. Reinstall Hermes with its official Windows installer or install Python 3.11+."
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Invoke-MemleafPython -PythonArgs @(
|
|
42
|
+
"-c",
|
|
43
|
+
"import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
$oldHermesHome = $env:HERMES_HOME
|
|
47
|
+
try {
|
|
48
|
+
$env:HERMES_HOME = $hermesHome
|
|
49
|
+
|
|
50
|
+
Write-Host "Installing memleaf from PyPI..."
|
|
51
|
+
|
|
52
|
+
$managedUv = Join-Path $hermesHome "bin\uv.exe"
|
|
53
|
+
$uvCommand = $null
|
|
54
|
+
if (Test-Path -LiteralPath $managedUv -PathType Leaf) {
|
|
55
|
+
$uvCommand = $managedUv
|
|
56
|
+
} else {
|
|
57
|
+
$foundUv = Get-Command uv -ErrorAction SilentlyContinue
|
|
58
|
+
if ($foundUv) {
|
|
59
|
+
$uvCommand = $foundUv.Source
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if ($uvCommand -and $script:MemleafPythonPrefix.Count -eq 0) {
|
|
64
|
+
& $uvCommand pip install --python $script:MemleafPython --upgrade memleaf
|
|
65
|
+
if ($LASTEXITCODE -ne 0) {
|
|
66
|
+
throw "uv could not install memleaf (exit code $LASTEXITCODE)"
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
& $script:MemleafPython @script:MemleafPythonPrefix -m pip --version *> $null
|
|
70
|
+
if ($LASTEXITCODE -ne 0) {
|
|
71
|
+
Invoke-MemleafPython -PythonArgs @("-m", "ensurepip", "--upgrade")
|
|
72
|
+
}
|
|
73
|
+
Invoke-MemleafPython -PythonArgs @("-m", "pip", "install", "--upgrade", "memleaf")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Write-Host "Configuring Hermes to use memleaf..."
|
|
77
|
+
Invoke-MemleafPython -PythonArgs @("-m", "memleaf", "install")
|
|
78
|
+
|
|
79
|
+
Write-Host ""
|
|
80
|
+
Write-Host "memleaf is installed and configured for Hermes."
|
|
81
|
+
Write-Host "Restart Hermes to use memleaf."
|
|
82
|
+
} finally {
|
|
83
|
+
if ($null -eq $oldHermesHome) {
|
|
84
|
+
Remove-Item Env:HERMES_HOME -ErrorAction SilentlyContinue
|
|
85
|
+
} else {
|
|
86
|
+
$env:HERMES_HOME = $oldHermesHome
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "memleaf"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
description = "A local-first Markdown memory core for AI agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
|
-
license = "
|
|
12
|
-
license-files = ["LICENSE"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
13
|
authors = [{name = "memleaf contributors"}]
|
|
14
14
|
keywords = ["ai-agents", "local-first", "markdown", "memory"]
|
|
15
15
|
classifiers = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Local-first Markdown memory core for AI agents."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.1.
|
|
3
|
+
__version__ = "0.1.4"
|
|
4
4
|
|
|
5
5
|
from .config import DEFAULT_CONFIG, default_config, load_config, save_config
|
|
6
6
|
from .frontmatter import FrontmatterError, dump_frontmatter, dump_yaml, load_yaml, parse_frontmatter
|
|
@@ -151,7 +151,15 @@ def resolve_executable(
|
|
|
151
151
|
candidates.extend(Path(candidate).expanduser() for candidate in known_paths)
|
|
152
152
|
for candidate in candidates:
|
|
153
153
|
try:
|
|
154
|
-
if candidate.is_file()
|
|
154
|
+
if not candidate.is_file():
|
|
155
|
+
continue
|
|
156
|
+
windows_launcher = os.name == "nt" and candidate.suffix.casefold() in {
|
|
157
|
+
".exe",
|
|
158
|
+
".cmd",
|
|
159
|
+
".bat",
|
|
160
|
+
".com",
|
|
161
|
+
}
|
|
162
|
+
if windows_launcher or os.access(candidate, os.X_OK):
|
|
155
163
|
return str(candidate.resolve())
|
|
156
164
|
except OSError:
|
|
157
165
|
continue
|
|
@@ -511,7 +519,10 @@ def atomic_replace_bytes(path: Path | str, data: bytes, *, mode: int = 0o600) ->
|
|
|
511
519
|
prefix=f".{target.name}.", suffix=".tmp", dir=str(target.parent)
|
|
512
520
|
)
|
|
513
521
|
temporary = Path(temporary_name)
|
|
514
|
-
|
|
522
|
+
try:
|
|
523
|
+
os.fchmod(descriptor, mode)
|
|
524
|
+
except (AttributeError, OSError):
|
|
525
|
+
pass
|
|
515
526
|
with os.fdopen(descriptor, "wb") as stream:
|
|
516
527
|
descriptor = None
|
|
517
528
|
stream.write(data)
|