memleaf 0.2.35__tar.gz → 0.2.36__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.2.35 → memleaf-0.2.36}/CHANGELOG.md +6 -0
- {memleaf-0.2.35/src/memleaf.egg-info → memleaf-0.2.36}/PKG-INFO +2 -2
- {memleaf-0.2.35 → memleaf-0.2.36}/README.en.md +1 -1
- {memleaf-0.2.35 → memleaf-0.2.36}/README.md +1 -1
- {memleaf-0.2.35 → memleaf-0.2.36}/pyproject.toml +1 -1
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/__init__.py +1 -1
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/hermes_provider/__init__.py +7 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/hermes_provider/plugin.yaml +1 -1
- {memleaf-0.2.35 → memleaf-0.2.36/src/memleaf.egg-info}/PKG-INFO +2 -2
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf.egg-info/SOURCES.txt +1 -0
- memleaf-0.2.36/tests/test_hermes_windows_subprocess.py +43 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/IMPLEMENTATION_PLAN.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/LICENSE +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/MANIFEST.in +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/RELEASE_CHECKLIST.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/capture-budget-design.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/config-migrations.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/core-refactor.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/evidence-retention.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/gate-evidence-boundary.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/general-processing.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/hermes-mcp-runtime.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/performance.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/processing-quality-acceptance.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/docs/v0.2.26-processing-status.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/examples/README.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/examples/basic_usage.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/examples/live_core_lifecycle_acceptance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/examples/live_processing_acceptance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/examples/mcp_stdio.ndjson +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/install.ps1 +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/install.sh +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/setup.cfg +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/__main__.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/adapters/__init__.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/adapters/antigravity.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/adapters/base.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/adapters/codex.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/adapters/hermes.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/admission.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/budget.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/capture.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/cli.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/compaction.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/config.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/create_coordinator.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/credentials.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/evidence_budget.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/evidence_policy.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/frontmatter.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/hermes_provider/README.md +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/hermes_provider/evidence_budget.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/hermes_runtime.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/host_events.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/host_runtime.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/inbox.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/index.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/inspection.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/installer.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/__init__.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/base.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/claude_compatible.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/gemini.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/openai_compatible.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/llm/router.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/locking.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/mcp_server.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/memory_commit.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/memory_planner.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/memory_writer.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/model_discovery.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/model_execution.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/models.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/native_index.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/native_registration.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/parallel_model.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/planning_context.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/process_common.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/process_jobs.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/process_journal.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/process_owner.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/processing.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/prompts.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/provenance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/recording_policy.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/redaction.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/retention.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/retrieval.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/retrieval_gate.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/scope_maintenance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/scope_state.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/service.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/source_policy.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/state_layout.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/target_reconciliation.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/turn_audit.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/turn_plan.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/update_coordinator.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/update_review.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/validation.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf/vault.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf.egg-info/dependency_links.txt +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf.egg-info/entry_points.txt +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/src/memleaf.egg-info/top_level.txt +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/__init__.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/semantic_fixtures.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_admission_noise.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_automatic_duplicate_noop_collision.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_candidate_polarity.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_codex_install.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_codex_native_cli.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_config_migrations_v028.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_context_budget.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_conversation_only.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_credential_safety.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_cross_host_acceptance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_cross_turn_dedupe_regressions.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_due_date_grounding.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_due_date_grounding_retry.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_email_actionable_coverage.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_evidence_budget.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_evidence_retention_policy.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_external_source_dates.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_extraction_quality_regressions.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_gate_capacity.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_gate_schema_repair.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_general_evidence_admission.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_general_tool_provenance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_global_todo_acceptance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_global_todo_query_no_write.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_global_todo_retrieval.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_hermes_native_registration.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_hermes_provider.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_hermes_runtime_install.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_hermes_stdio_transport.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_hermes_transport_evidence.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_host_events.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_host_runtime_contract.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_inspection_state_v028.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_install.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_long_run_hygiene.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_maintenance_v2.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_model_discovery.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_model_owned_fields.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_new_scope_source_grounding.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_partial_retry_idempotency.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_phase2_model_decisions.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_process_jobs.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_process_owner_locking.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_processing_contract_v026.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_processing_observability_concurrency.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_pypi_install.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_read_only_deferred_isolation.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_retrieval_gate.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_retrieval_v2.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_review_source_context.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_revision_digest.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_session_lineage.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_shared_memory_refactor.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_source_neutral_todos_v028.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_a.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b1.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b2a.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b2b.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3a_commit.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3a_contract.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3b_native_context.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3b_native_index.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3b_scope.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3c_retrieval.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_b3d_scope_maintenance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_c1_mcp.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_c2_init.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_stage_c3_packaging.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_state_layout_v028.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_summary_date_grounding_integration.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_target_reconciliation.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_target_reconciliation_integration.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_todo_state_recovery.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_update_review.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_update_target_recovery.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_upgrade_preserves_vault.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v023_scope_correction.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v2_gate_limits.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v2_host_flow.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v2_mcp_flow.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v2_nomatch_semantics.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_v2_search_gate_acceptance.py +0 -0
- {memleaf-0.2.35 → memleaf-0.2.36}/tests/test_whole_unit_bindings.py +0 -0
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to memleaf are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.2.36 — 2026-09-08
|
|
6
|
+
|
|
7
|
+
- Prevent the Hermes MemoryProvider from opening a visible console/Windows Terminal window whenever it starts its private `memleaf-mcp` stdio child on Windows. Provider-owned MCP launches now use `subprocess.CREATE_NO_WINDOW`; stdin/stdout pipes, stderr suppression, timeout handling, process reuse and shutdown semantics are unchanged.
|
|
8
|
+
- Add deterministic regression coverage for the Windows creation flag, the non-Windows zero-flag path, and the exact `Popen` stdio contract.
|
|
9
|
+
- Correct the README release banner that was still displaying 0.2.34 after the 0.2.35 publication.
|
|
10
|
+
|
|
5
11
|
## 0.2.35 — 2026-09-08
|
|
6
12
|
|
|
7
13
|
- Add safe structural model-call telemetry across successful, deferred, and failed processing: call/retry/failure counts, model-request and stage wall-clock timing, input/output lengths, and maximum in-flight concurrency are retained without prompts, responses, memory bodies, credentials, provider secrets, URLs, or raw exception text.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memleaf
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.36
|
|
4
4
|
Summary: A local-first Markdown memory core for AI agents
|
|
5
5
|
Author: memleaf contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,7 +23,7 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
25
25
|
|
|
26
|
-
> **版本:0.2.
|
|
26
|
+
> **版本:0.2.36。**
|
|
27
27
|
> 记忆只从用户与 Agent 的可见对话提炼。Agent 已在回复中整理的事实、项目进展和明确待办可作为来源;邮件、附件、网页和终端等工具原文不进入记忆提炼。模型负责保留原话中的不确定性,现有记忆仅用于比较、去重和更新。Markdown 仍是唯一事实源。
|
|
28
28
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
29
29
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[中文](README.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **Version: 0.2.
|
|
7
|
+
> **Version: 0.2.36.**
|
|
8
8
|
> Automatic extraction now uses only the current turn's visible user input and final assistant reply. Raw tool output, attachments, web/file/terminal payloads and legacy tool-evidence bodies are not new source evidence; existing or retrieved memory remains comparison context rather than source authority. Background processing is persisted as a local job and can be checked through the read-only `process_status` MCP tool; failed work remains retryable and fail closed. The release also tightens source/date grounding, target reconciliation, duplicate/no-op handling and semantic review before writes. Markdown remains the sole source of truth with no SQLite runtime dependency. Acceptance covers deterministic regression suites and synthetic inputs; it does not claim real-mail or customer-business acceptance.
|
|
9
9
|
> **The current release supports Hermes and Codex.** Antigravity is not detected, installed, or configured.
|
|
10
10
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **版本:0.2.
|
|
7
|
+
> **版本:0.2.36。**
|
|
8
8
|
> 记忆只从用户与 Agent 的可见对话提炼。Agent 已在回复中整理的事实、项目进展和明确待办可作为来源;邮件、附件、网页和终端等工具原文不进入记忆提炼。模型负责保留原话中的不确定性,现有记忆仅用于比较、去重和更新。Markdown 仍是唯一事实源。
|
|
9
9
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Local-first Markdown memory core for AI agents."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.2.
|
|
3
|
+
__version__ = "0.2.36"
|
|
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
|
|
@@ -1025,6 +1025,12 @@ def _write_json(path: Path, value: Mapping[str, Any]) -> None:
|
|
|
1025
1025
|
os.replace(temporary, path)
|
|
1026
1026
|
|
|
1027
1027
|
|
|
1028
|
+
def _mcp_creationflags() -> int:
|
|
1029
|
+
"""Hide the provider-owned MCP child console on Windows only."""
|
|
1030
|
+
|
|
1031
|
+
return subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0
|
|
1032
|
+
|
|
1033
|
+
|
|
1028
1034
|
class _MCPClient:
|
|
1029
1035
|
"""Small synchronous JSON-RPC client for memleaf's stdio MCP server."""
|
|
1030
1036
|
|
|
@@ -1105,6 +1111,7 @@ class _MCPClient:
|
|
|
1105
1111
|
encoding="utf-8",
|
|
1106
1112
|
errors="strict",
|
|
1107
1113
|
bufsize=1,
|
|
1114
|
+
creationflags=_mcp_creationflags(),
|
|
1108
1115
|
)
|
|
1109
1116
|
self._start_stdout_reader_locked(self._process)
|
|
1110
1117
|
initialize_result = self._request_locked(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memleaf
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.36
|
|
4
4
|
Summary: A local-first Markdown memory core for AI agents
|
|
5
5
|
Author: memleaf contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,7 +23,7 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
25
25
|
|
|
26
|
-
> **版本:0.2.
|
|
26
|
+
> **版本:0.2.36。**
|
|
27
27
|
> 记忆只从用户与 Agent 的可见对话提炼。Agent 已在回复中整理的事实、项目进展和明确待办可作为来源;邮件、附件、网页和终端等工具原文不进入记忆提炼。模型负责保留原话中的不确定性,现有记忆仅用于比较、去重和更新。Markdown 仍是唯一事实源。
|
|
28
28
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
29
29
|
|
|
@@ -131,6 +131,7 @@ tests/test_hermes_provider.py
|
|
|
131
131
|
tests/test_hermes_runtime_install.py
|
|
132
132
|
tests/test_hermes_stdio_transport.py
|
|
133
133
|
tests/test_hermes_transport_evidence.py
|
|
134
|
+
tests/test_hermes_windows_subprocess.py
|
|
134
135
|
tests/test_host_events.py
|
|
135
136
|
tests/test_host_runtime_contract.py
|
|
136
137
|
tests/test_inspection_state_v028.py
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import unittest
|
|
4
|
+
from unittest.mock import Mock, patch
|
|
5
|
+
|
|
6
|
+
from tests.test_hermes_provider import provider_module
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HermesWindowsSubprocessTests(unittest.TestCase):
|
|
10
|
+
def test_windows_creationflags_use_create_no_window(self):
|
|
11
|
+
flag = 0x08000000
|
|
12
|
+
with (
|
|
13
|
+
patch.object(provider_module.os, "name", "nt"),
|
|
14
|
+
patch.object(provider_module.subprocess, "CREATE_NO_WINDOW", flag, create=True),
|
|
15
|
+
):
|
|
16
|
+
self.assertEqual(provider_module._mcp_creationflags(), flag)
|
|
17
|
+
|
|
18
|
+
def test_non_windows_creationflags_are_zero(self):
|
|
19
|
+
with patch.object(provider_module.os, "name", "posix"):
|
|
20
|
+
self.assertEqual(provider_module._mcp_creationflags(), 0)
|
|
21
|
+
|
|
22
|
+
def test_mcp_popen_receives_creationflags(self):
|
|
23
|
+
client = provider_module._MCPClient("memleaf-mcp", ".", 5.0)
|
|
24
|
+
process = Mock()
|
|
25
|
+
flag = 0x08000000
|
|
26
|
+
with (
|
|
27
|
+
patch.object(provider_module, "_mcp_creationflags", return_value=flag),
|
|
28
|
+
patch.object(provider_module.subprocess, "Popen", return_value=process) as popen,
|
|
29
|
+
patch.object(client, "_resolve_command", return_value="memleaf-mcp"),
|
|
30
|
+
patch.object(client, "_start_stdout_reader_locked"),
|
|
31
|
+
patch.object(client, "_request_locked", return_value={}),
|
|
32
|
+
patch.object(client, "_send_locked"),
|
|
33
|
+
):
|
|
34
|
+
client._start_locked()
|
|
35
|
+
|
|
36
|
+
self.assertEqual(popen.call_args.kwargs.get("creationflags"), flag)
|
|
37
|
+
self.assertIs(popen.call_args.kwargs.get("stdin"), provider_module.subprocess.PIPE)
|
|
38
|
+
self.assertIs(popen.call_args.kwargs.get("stdout"), provider_module.subprocess.PIPE)
|
|
39
|
+
self.assertIs(popen.call_args.kwargs.get("stderr"), provider_module.subprocess.DEVNULL)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|