memplex 3.2.0__tar.gz → 3.2.2__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.
Files changed (132) hide show
  1. memplex-3.2.2/LICENSE +21 -0
  2. {memplex-3.2.0 → memplex-3.2.2}/PKG-INFO +4 -2
  3. memplex-3.2.2/README.md +130 -0
  4. memplex-3.2.2/memplex/__init__.py +32 -0
  5. memplex-3.2.2/memplex/__main__.py +7 -0
  6. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/.claude-plugin/plugin.json +3 -3
  7. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/.mcp.json +2 -2
  8. memplex-3.2.2/memplex/_plugin/hooks/hooks.json +81 -0
  9. memplex-3.2.2/memplex/_plugin/scripts/hook-runner.py +418 -0
  10. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/skills/mem-explore/SKILL.md +5 -5
  11. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/skills/mem-manage/SKILL.md +7 -7
  12. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/skills/mem-search/SKILL.md +2 -2
  13. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/skills/mem-write/SKILL.md +5 -5
  14. memplex-3.2.2/memplex/adapters/__init__.py +14 -0
  15. memplex-3.2.2/memplex/adapters/agent_installer.py +928 -0
  16. memplex-3.2.2/memplex/adapters/agent_runtime.py +399 -0
  17. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/adapters/claude_skill.py +22 -22
  18. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/adapters/cli.py +225 -60
  19. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/adapters/http_api.py +37 -29
  20. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/adapters/mcp_server.py +147 -25
  21. memplex-3.2.2/memplex/benchmarks/__init__.py +83 -0
  22. memplex-3.2.2/memplex/benchmarks/base.py +268 -0
  23. memplex-3.2.2/memplex/benchmarks/benchmark_cli.py +208 -0
  24. memplex-3.2.2/memplex/benchmarks/evaluator.py +552 -0
  25. memplex-3.2.2/memplex/benchmarks/loader.py +342 -0
  26. memplex-3.2.2/memplex/benchmarks/locomo.py +677 -0
  27. memplex-3.2.2/memplex/benchmarks/memory_eval.py +756 -0
  28. memplex-3.2.2/memplex/benchmarks/memory_metrics.py +151 -0
  29. memplex-3.2.2/memplex/benchmarks/metrics.py +551 -0
  30. memplex-3.2.2/memplex/benchmarks/nq_trivia.py +1073 -0
  31. memplex-3.2.2/memplex/benchmarks/popqa_hotpot.py +958 -0
  32. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/compaction.py +31 -56
  33. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/config.py +42 -37
  34. memplex-3.2.2/memplex/core/__init__.py +13 -0
  35. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/associator/domain_classifier.py +88 -10
  36. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/associator/entity_aligner.py +17 -22
  37. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/associator/ref_linker.py +64 -35
  38. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/associator/term_mapper.py +8 -9
  39. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/dictionaries/__init__.py +3 -2
  40. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/engine.py +124 -91
  41. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/docx.py +8 -3
  42. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/image.py +13 -7
  43. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/markdown.py +69 -26
  44. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/pdf.py +33 -20
  45. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/vision_mapper.py +15 -16
  46. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/handlers/clipboard.py +5 -12
  47. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/handlers/file_handler.py +19 -12
  48. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/handlers/url_handler.py +24 -19
  49. memplex-3.2.2/memplex/core/hooks/__init__.py +11 -0
  50. memplex-3.2.2/memplex/core/hooks/collector.py +241 -0
  51. memplex-3.2.2/memplex/core/hooks/hook_event.py +38 -0
  52. memplex-3.2.2/memplex/core/hooks/registry.py +128 -0
  53. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/__init__.py +6 -6
  54. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/enhancer.py +11 -17
  55. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/fallback_chain.py +12 -6
  56. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/injection_guard.py +6 -6
  57. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/provider.py +5 -5
  58. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/providers/__init__.py +5 -3
  59. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/providers/anthropic.py +3 -4
  60. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/providers/local.py +6 -5
  61. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/providers/rule_based.py +31 -9
  62. memplex-3.2.2/memplex/logging_utils.py +270 -0
  63. memplex-3.2.2/memplex/metrics.py +382 -0
  64. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/__init__.py +47 -47
  65. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/feedback.py +2 -2
  66. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/memory.py +11 -4
  67. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/misc.py +10 -6
  68. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/search.py +3 -3
  69. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/task.py +2 -2
  70. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/processing/graph_builder.py +43 -39
  71. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/processing/merger/__init__.py +1 -1
  72. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/processing/merger/confidence_calculator.py +7 -10
  73. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/processing/merger/conflict_resolver.py +17 -9
  74. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/retrieval/dedup.py +10 -19
  75. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/retrieval/embedding.py +13 -25
  76. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/retrieval/reranker.py +6 -11
  77. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/service.py +314 -95
  78. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/__init__.py +20 -21
  79. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/base.py +2 -2
  80. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/changelog.py +4 -6
  81. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/feedback.py +48 -33
  82. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/lite/__init__.py +1 -1
  83. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/lite/store.py +86 -92
  84. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/storage/vector.py +13 -11
  85. memplex-3.2.2/memplex/wiki/__init__.py +11 -0
  86. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/wiki/community.py +26 -26
  87. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/wiki/compiler.py +48 -57
  88. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/wiki/generator.py +19 -15
  89. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/wiki/search.py +40 -30
  90. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/worker.py +42 -27
  91. {memplex-3.2.0 → memplex-3.2.2}/memplex.egg-info/PKG-INFO +4 -2
  92. memplex-3.2.2/memplex.egg-info/SOURCES.txt +118 -0
  93. memplex-3.2.2/memplex.egg-info/entry_points.txt +2 -0
  94. {memplex-3.2.0 → memplex-3.2.2}/memplex.egg-info/requires.txt +1 -1
  95. memplex-3.2.2/memplex.egg-info/top_level.txt +1 -0
  96. memplex-3.2.2/pyproject.toml +106 -0
  97. memplex-3.2.2/tests/test_agent_hot_paths.py +224 -0
  98. memplex-3.2.2/tests/test_agent_runtime.py +199 -0
  99. {memplex-3.2.0 → memplex-3.2.2}/tests/test_associators.py +7 -9
  100. {memplex-3.2.0 → memplex-3.2.2}/tests/test_config.py +41 -42
  101. {memplex-3.2.0 → memplex-3.2.2}/tests/test_core_engine.py +12 -12
  102. {memplex-3.2.0 → memplex-3.2.2}/tests/test_graph_builder.py +63 -34
  103. memplex-3.2.2/tests/test_hooks.py +1312 -0
  104. memplex-3.2.2/tests/test_install_scripts.py +171 -0
  105. {memplex-3.2.0 → memplex-3.2.2}/tests/test_llm.py +38 -39
  106. {memplex-3.2.0 → memplex-3.2.2}/tests/test_models.py +16 -15
  107. {memplex-3.2.0 → memplex-3.2.2}/tests/test_service.py +26 -22
  108. {memplex-3.2.0 → memplex-3.2.2}/tests/test_storage.py +75 -40
  109. memplex-3.2.0/memnex/__init__.py +0 -31
  110. memplex-3.2.0/memnex/__main__.py +0 -6
  111. memplex-3.2.0/memnex/_plugin/hooks/hooks.json +0 -43
  112. memplex-3.2.0/memnex/_plugin/scripts/hook-runner.py +0 -166
  113. memplex-3.2.0/memnex/adapters/__init__.py +0 -14
  114. memplex-3.2.0/memnex/core/__init__.py +0 -13
  115. memplex-3.2.0/memnex/wiki/__init__.py +0 -11
  116. memplex-3.2.0/memplex.egg-info/SOURCES.txt +0 -94
  117. memplex-3.2.0/memplex.egg-info/entry_points.txt +0 -2
  118. memplex-3.2.0/memplex.egg-info/top_level.txt +0 -1
  119. memplex-3.2.0/pyproject.toml +0 -71
  120. memplex-3.2.0/tests/test_hooks.py +0 -453
  121. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/_plugin/__init__.py +0 -0
  122. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/associator/__init__.py +3 -3
  123. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/extractors/__init__.py +2 -2
  124. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/core/handlers/__init__.py +0 -0
  125. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/llm/sanitizer.py +0 -0
  126. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/graph.py +1 -1
  127. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/paragraph.py +0 -0
  128. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/models/source.py +1 -1
  129. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/processing/__init__.py +0 -0
  130. {memplex-3.2.0/memnex → memplex-3.2.2/memplex}/retrieval/__init__.py +0 -0
  131. {memplex-3.2.0 → memplex-3.2.2}/memplex.egg-info/dependency_links.txt +0 -0
  132. {memplex-3.2.0 → memplex-3.2.2}/setup.cfg +0 -0
memplex-3.2.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Memplex
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,8 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memplex
3
- Version: 3.2.0
3
+ Version: 3.2.2
4
4
  Summary: Memplex - Memory Complex: multi-agent knowledge graph memory system with 3-layer retrieval
5
5
  Requires-Python: >=3.11
6
+ License-File: LICENSE
6
7
  Requires-Dist: pyyaml>=6.0
7
8
  Requires-Dist: numpy>=1.24.0
8
9
  Requires-Dist: requests>=2.28.0
@@ -30,8 +31,9 @@ Requires-Dist: asyncpg>=0.29.0; extra == "postgres"
30
31
  Provides-Extra: neo4j
31
32
  Requires-Dist: neo4j>=5.0.0; extra == "neo4j"
32
33
  Provides-Extra: all
33
- Requires-Dist: memnex[embedding,extractors,graph,http,llm,vector]; extra == "all"
34
+ Requires-Dist: memplex[embedding,extractors,graph,http,llm,vector]; extra == "all"
34
35
  Provides-Extra: dev
35
36
  Requires-Dist: pytest>=7.0; extra == "dev"
36
37
  Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
37
38
  Requires-Dist: ruff>=0.1.0; extra == "dev"
39
+ Dynamic: license-file
@@ -0,0 +1,130 @@
1
+ # Memplex
2
+
3
+ **Memplex** is a persistent knowledge graph memory system for AI agents. It extracts structured knowledge from documents, URLs, and conversations, then provides 3-layer retrieval across sessions.
4
+
5
+ ## Features
6
+
7
+ - **4 Memory Types**: Function (procedural), Fact (declarative), Preference (user prefs), Observation (runtime events)
8
+ - **3-Layer Retrieval**: Search → Timeline → Get (10x token savings vs fetching everything)
9
+ - **5-Dim Reranker**: raw_relevance, semantic_similarity, recency_decay, source_authority, frequency
10
+ - **5-Stage Compaction**: Extract → Dedup → Summarize → Prune → Archive
11
+ - **Wiki Layer**: WikiCompiler + DualIndexSearch (FTS + vector RRF) + GraphRAG community detection
12
+ - **Lifecycle Hooks**: Auto-collect observations from tool usage, compact on session end
13
+
14
+ ## Installation
15
+
16
+ ### Claude Code Plugin
17
+
18
+ **Option 1: Local plugin (for development)**
19
+ ```bash
20
+ # Clone and install locally
21
+ cd plugin
22
+ /plugin install ./plugin
23
+ ```
24
+
25
+ **Option 2: Via marketplace**
26
+ ```bash
27
+ /plugin marketplace add ./marketplace.json
28
+ /plugin install memplex
29
+ ```
30
+
31
+ **Option 3: pip install**
32
+ ```bash
33
+ pip install memplex
34
+ ```
35
+
36
+ ### From Source
37
+
38
+ ```bash
39
+ git clone https://github.com/articultur/memplex.git
40
+ cd memplex
41
+ pip install -e .
42
+ ```
43
+
44
+ ### Agent One-Command Install
45
+
46
+ For a machine that does not have this repository checked out, install Memplex
47
+ into a detected local agent with:
48
+
49
+ ```bash
50
+ curl -fsSL https://raw.githubusercontent.com/articultur/memplex/main/scripts/install-agent.sh | bash
51
+ ```
52
+
53
+ By default the script installs Memplex from GitHub into a persistent Python
54
+ environment at `~/.local/share/memplex/agent-venv`, detects local Codex, Claude
55
+ Code, OpenClaw, and Hermes config directories/commands, then registers Memplex
56
+ with each detected agent. It uses `uv` when available and falls back to
57
+ `python -m venv` plus `pip`.
58
+
59
+ Install a specific agent:
60
+
61
+ ```bash
62
+ curl -fsSL https://raw.githubusercontent.com/articultur/memplex/main/scripts/install-agent.sh | \
63
+ bash -s -- --agent hermes --package memplex --project-path "$PWD" --user-id "$USER"
64
+ ```
65
+
66
+ Install every supported agent config on this machine:
67
+
68
+ ```bash
69
+ curl -fsSL https://raw.githubusercontent.com/articultur/memplex/main/scripts/install-agent.sh | \
70
+ bash -s -- --agent all --project-path "$PWD"
71
+ ```
72
+
73
+ Uninstall:
74
+
75
+ ```bash
76
+ curl -fsSL https://raw.githubusercontent.com/articultur/memplex/main/scripts/install-agent.sh | \
77
+ bash -s -- --agent hermes --uninstall
78
+ ```
79
+
80
+ ## Claude Code Setup
81
+
82
+ After installation, initialize Memplex:
83
+
84
+ ```bash
85
+ memplex config init
86
+ ```
87
+
88
+ This creates `memplex.yaml` with your configuration.
89
+
90
+ ## Quick Start
91
+
92
+ ```bash
93
+ # Write content to memory
94
+ memplex write "Python list comprehensions are faster than loops"
95
+
96
+ # Query memory
97
+ memplex query "python performance"
98
+
99
+ # Run compaction
100
+ memplex compact
101
+
102
+ # Health check
103
+ memplex health
104
+ ```
105
+
106
+ ## Adapters
107
+
108
+ | Adapter | Entry Point | Description |
109
+ |---------|------------|-------------|
110
+ | CLI | `memplex` / `python -m memplex` | 9 subcommands |
111
+ | HTTP API | `memplex.adapters.http_api` | FastAPI with 11 REST endpoints |
112
+ | MCP | `memplex.adapters.mcp_server` | stdio JSON-RPC, 9 tools |
113
+ | Claude Skill | `plugin/skills/` | Claude Code SKILL.md files |
114
+
115
+ ## Configuration
116
+
117
+ `memplex config init` creates `memplex.yaml`. Override via env vars `MEMPLEX_*`.
118
+
119
+ ## Storage
120
+
121
+ - **Default**: LiteMemoryStore (in-memory + JSON persistence at `.memplex/memory.json`)
122
+ - **Optional**: ChromaDB (vector embeddings), SQLite/Postgres (feedback)
123
+
124
+ ## Privacy
125
+
126
+ `<private>content</private>` tags prevent storage of tagged content.
127
+
128
+ ## License
129
+
130
+ MIT
@@ -0,0 +1,32 @@
1
+ """Memplex -- multi-agent memory system.
2
+
3
+ Primary entry point::
4
+
5
+ from memplex import MemplexService
6
+
7
+ svc = MemplexService()
8
+ result = svc.query("登录函数在哪")
9
+
10
+ CLI usage::
11
+
12
+ memplex query "search text"
13
+ memplex write --text "content"
14
+ memplex health
15
+ """
16
+
17
+ from memplex.core import CoreEngine
18
+ from memplex.service import MemplexService
19
+
20
+ __all__ = ["CoreEngine", "MemplexService", "main"]
21
+
22
+
23
+ def main() -> None:
24
+ """CLI entry point for ``memplex`` command.
25
+
26
+ Delegates to :func:`memplex.adapters.cli.main`.
27
+ """
28
+ import sys
29
+
30
+ from memplex.adapters.cli import main as cli_main
31
+
32
+ sys.exit(cli_main())
@@ -0,0 +1,7 @@
1
+ """Entry point for ``python -m memplex``."""
2
+
3
+ import sys
4
+
5
+ from memplex.adapters.cli import main
6
+
7
+ sys.exit(main())
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "memplex",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
4
4
  "description": "Multi-agent memory system -- persistent knowledge graph with 3-layer retrieval, compaction, and wiki",
5
5
  "author": {
6
6
  "name": "articultur"
7
7
  },
8
- "repository": "https://github.com/articultur/MemNex",
8
+ "repository": "https://github.com/articultur/Memplex",
9
9
  "license": "Apache-2.0",
10
10
  "keywords": [
11
11
  "claude",
@@ -20,5 +20,5 @@
20
20
  "python",
21
21
  "fastapi"
22
22
  ],
23
- "homepage": "https://github.com/articultur/MemNex#readme"
23
+ "homepage": "https://github.com/articultur/Memplex#readme"
24
24
  }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "mcpServers": {
3
- "memnex": {
3
+ "memplex": {
4
4
  "type": "stdio",
5
5
  "command": "python",
6
- "args": ["-m", "memnex.adapters.mcp_server"]
6
+ "args": ["-m", "memplex.adapters.mcp_server"]
7
7
  }
8
8
  }
9
9
  }
@@ -0,0 +1,81 @@
1
+ {
2
+ "description": "Memplex memory system hooks",
3
+ "hooks": {
4
+ "Setup": [
5
+ {
6
+ "matcher": "*",
7
+ "hooks": [
8
+ {
9
+ "type": "command",
10
+ "shell": "bash",
11
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" setup",
12
+ "timeout": 300
13
+ }
14
+ ]
15
+ }
16
+ ],
17
+ "SessionStart": [
18
+ {
19
+ "matcher": "startup|resume|clear|compact",
20
+ "hooks": [
21
+ {
22
+ "type": "command",
23
+ "shell": "bash",
24
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" session-start",
25
+ "timeout": 60
26
+ }
27
+ ]
28
+ }
29
+ ],
30
+ "UserPromptSubmit": [
31
+ {
32
+ "hooks": [
33
+ {
34
+ "type": "command",
35
+ "shell": "bash",
36
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" prompt-submit",
37
+ "timeout": 30
38
+ }
39
+ ]
40
+ }
41
+ ],
42
+ "PreToolUse": [
43
+ {
44
+ "matcher": "*",
45
+ "hooks": [
46
+ {
47
+ "type": "command",
48
+ "shell": "bash",
49
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" file-context",
50
+ "timeout": 60
51
+ }
52
+ ]
53
+ }
54
+ ],
55
+ "PostToolUse": [
56
+ {
57
+ "matcher": "*",
58
+ "hooks": [
59
+ {
60
+ "type": "command",
61
+ "shell": "bash",
62
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" observation \"$MEMPLEX_TOOL_NAME\" \"$MEMPLEX_SESSION_ID\"",
63
+ "timeout": 120
64
+ }
65
+ ]
66
+ }
67
+ ],
68
+ "Stop": [
69
+ {
70
+ "hooks": [
71
+ {
72
+ "type": "command",
73
+ "shell": "bash",
74
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${MEMPLEX_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/articultur/memplex\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/articultur/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/hook-runner.py\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"memplex: hook-runner.py not found\" >&2; exit 1; }; _PY=\"${MEMPLEX_PYTHON:-$(command -v python3 || command -v python || true)}\"; [ -n \"$_PY\" ] || { echo \"memplex: python not found\" >&2; exit 1; }; \"$_PY\" \"$_P/scripts/hook-runner.py\" summarize",
75
+ "timeout": 120
76
+ }
77
+ ]
78
+ }
79
+ ]
80
+ }
81
+ }