memos-engine 0.1.0__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.
- memos_engine-0.1.0/.github/workflows/ci.yml +18 -0
- memos_engine-0.1.0/.github/workflows/release.yml +21 -0
- memos_engine-0.1.0/.gitignore +222 -0
- memos_engine-0.1.0/.python-version +1 -0
- memos_engine-0.1.0/AGENTS.md +150 -0
- memos_engine-0.1.0/AGENTS_EXAMPLE.md +113 -0
- memos_engine-0.1.0/CHANGELOG.md +11 -0
- memos_engine-0.1.0/LICENSE +21 -0
- memos_engine-0.1.0/PKG-INFO +296 -0
- memos_engine-0.1.0/README.md +271 -0
- memos_engine-0.1.0/memos/__init__.py +0 -0
- memos_engine-0.1.0/memos/api/__init__.py +0 -0
- memos_engine-0.1.0/memos/api/main.py +267 -0
- memos_engine-0.1.0/memos/api/schemas.py +118 -0
- memos_engine-0.1.0/memos/cli/__init__.py +0 -0
- memos_engine-0.1.0/memos/cli/main.py +430 -0
- memos_engine-0.1.0/memos/core/__init__.py +0 -0
- memos_engine-0.1.0/memos/core/db.py +293 -0
- memos_engine-0.1.0/memos/core/migrations/0001_init.sql +66 -0
- memos_engine-0.1.0/memos/core/migrations/0002_vec.sql +5 -0
- memos_engine-0.1.0/memos/core/migrations/0003_prompt_version.sql +3 -0
- memos_engine-0.1.0/memos/core/migrations/0004_memory_fts.sql +24 -0
- memos_engine-0.1.0/memos/core/migrations/__init__.py +0 -0
- memos_engine-0.1.0/memos/core/models.py +65 -0
- memos_engine-0.1.0/memos/core/schema.sql +73 -0
- memos_engine-0.1.0/memos/indexer/__init__.py +0 -0
- memos_engine-0.1.0/memos/indexer/base.py +41 -0
- memos_engine-0.1.0/memos/indexer/diff.py +24 -0
- memos_engine-0.1.0/memos/indexer/go.py +209 -0
- memos_engine-0.1.0/memos/indexer/typescript.py +201 -0
- memos_engine-0.1.0/memos/mcp/__init__.py +0 -0
- memos_engine-0.1.0/memos/mcp/server.py +734 -0
- memos_engine-0.1.0/memos/query/__init__.py +0 -0
- memos_engine-0.1.0/memos/query/core.py +689 -0
- memos_engine-0.1.0/memos/search/__init__.py +0 -0
- memos_engine-0.1.0/memos/search/base.py +36 -0
- memos_engine-0.1.0/memos/search/embeddings.py +30 -0
- memos_engine-0.1.0/memos/search/sqlite_vec_store.py +57 -0
- memos_engine-0.1.0/pyproject.toml +99 -0
- memos_engine-0.1.0/tests/__init__.py +0 -0
- memos_engine-0.1.0/tests/conftest.py +11 -0
- memos_engine-0.1.0/tests/fixtures/__init__.py +0 -0
- memos_engine-0.1.0/tests/fixtures/go_mini/__init__.py +0 -0
- memos_engine-0.1.0/tests/fixtures/go_mini/src/main.go +11 -0
- memos_engine-0.1.0/tests/fixtures/go_mini/src/types.go +12 -0
- memos_engine-0.1.0/tests/fixtures/go_mini/src/utils.go +13 -0
- memos_engine-0.1.0/tests/fixtures/import_cycle/src/a.ts +5 -0
- memos_engine-0.1.0/tests/fixtures/import_cycle/src/b.ts +5 -0
- memos_engine-0.1.0/tests/fixtures/typescript_mini/src/index.ts +7 -0
- memos_engine-0.1.0/tests/fixtures/typescript_mini/src/types.ts +6 -0
- memos_engine-0.1.0/tests/fixtures/typescript_mini/src/utils.ts +9 -0
- memos_engine-0.1.0/tests/test_api.py +136 -0
- memos_engine-0.1.0/tests/test_cli_index.py +215 -0
- memos_engine-0.1.0/tests/test_cli_query.py +112 -0
- memos_engine-0.1.0/tests/test_crud.py +260 -0
- memos_engine-0.1.0/tests/test_dependency_graph.py +216 -0
- memos_engine-0.1.0/tests/test_go_indexer.py +194 -0
- memos_engine-0.1.0/tests/test_hygiene.py +183 -0
- memos_engine-0.1.0/tests/test_impact.py +192 -0
- memos_engine-0.1.0/tests/test_llm_summary.py +261 -0
- memos_engine-0.1.0/tests/test_mcp.py +305 -0
- memos_engine-0.1.0/tests/test_memory_hygiene.py +117 -0
- memos_engine-0.1.0/tests/test_migrations.py +40 -0
- memos_engine-0.1.0/tests/test_query.py +299 -0
- memos_engine-0.1.0/tests/test_reindex.py +89 -0
- memos_engine-0.1.0/tests/test_resolver.py +451 -0
- memos_engine-0.1.0/tests/test_schema.py +23 -0
- memos_engine-0.1.0/tests/test_semantic_search.py +216 -0
- memos_engine-0.1.0/tests/test_typescript_indexer.py +183 -0
- memos_engine-0.1.0/uv.lock +1799 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
ci:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
python-version: ["3.12"]
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: astral-sh/setup-uv@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: ${{ matrix.python-version }}
|
|
16
|
+
- run: uv sync
|
|
17
|
+
- run: uv run ruff check .
|
|
18
|
+
- run: uv run pytest
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: astral-sh/setup-uv@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.12"
|
|
15
|
+
- run: uv sync
|
|
16
|
+
- run: uv run ruff check .
|
|
17
|
+
- run: uv run pytest
|
|
18
|
+
- run: uv build
|
|
19
|
+
- run: uv publish
|
|
20
|
+
env:
|
|
21
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
MEMORY_OS_ARCHITECTURE.md
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib/
|
|
20
|
+
lib64/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
*.py.cover
|
|
52
|
+
*.lcov
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
cover/
|
|
56
|
+
|
|
57
|
+
# Translations
|
|
58
|
+
*.mo
|
|
59
|
+
*.pot
|
|
60
|
+
|
|
61
|
+
# Django stuff:
|
|
62
|
+
*.log
|
|
63
|
+
local_settings.py
|
|
64
|
+
db.sqlite3
|
|
65
|
+
db.sqlite3-journal
|
|
66
|
+
|
|
67
|
+
# Flask stuff:
|
|
68
|
+
instance/
|
|
69
|
+
.webassets-cache
|
|
70
|
+
|
|
71
|
+
# Scrapy stuff:
|
|
72
|
+
.scrapy
|
|
73
|
+
|
|
74
|
+
# Sphinx documentation
|
|
75
|
+
docs/_build/
|
|
76
|
+
|
|
77
|
+
# PyBuilder
|
|
78
|
+
.pybuilder/
|
|
79
|
+
target/
|
|
80
|
+
|
|
81
|
+
# Jupyter Notebook
|
|
82
|
+
.ipynb_checkpoints
|
|
83
|
+
|
|
84
|
+
# IPython
|
|
85
|
+
profile_default/
|
|
86
|
+
ipython_config.py
|
|
87
|
+
|
|
88
|
+
# pyenv
|
|
89
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
90
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
91
|
+
# .python-version
|
|
92
|
+
|
|
93
|
+
# pipenv
|
|
94
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
95
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
96
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
97
|
+
# install all needed dependencies.
|
|
98
|
+
# Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# UV
|
|
101
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
102
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
103
|
+
# commonly ignored for libraries.
|
|
104
|
+
# uv.lock
|
|
105
|
+
|
|
106
|
+
# poetry
|
|
107
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
108
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
109
|
+
# commonly ignored for libraries.
|
|
110
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
111
|
+
# poetry.lock
|
|
112
|
+
# poetry.toml
|
|
113
|
+
|
|
114
|
+
# pdm
|
|
115
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
116
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
117
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
118
|
+
# pdm.lock
|
|
119
|
+
# pdm.toml
|
|
120
|
+
.pdm-python
|
|
121
|
+
.pdm-build/
|
|
122
|
+
|
|
123
|
+
# pixi
|
|
124
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
125
|
+
# pixi.lock
|
|
126
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
127
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
128
|
+
.pixi/*
|
|
129
|
+
!.pixi/config.toml
|
|
130
|
+
|
|
131
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
132
|
+
__pypackages__/
|
|
133
|
+
|
|
134
|
+
# Celery stuff
|
|
135
|
+
celerybeat-schedule*
|
|
136
|
+
celerybeat.pid
|
|
137
|
+
|
|
138
|
+
# Redis
|
|
139
|
+
*.rdb
|
|
140
|
+
*.aof
|
|
141
|
+
*.pid
|
|
142
|
+
|
|
143
|
+
# RabbitMQ
|
|
144
|
+
mnesia/
|
|
145
|
+
rabbitmq/
|
|
146
|
+
rabbitmq-data/
|
|
147
|
+
|
|
148
|
+
# ActiveMQ
|
|
149
|
+
activemq-data/
|
|
150
|
+
|
|
151
|
+
# SageMath parsed files
|
|
152
|
+
*.sage.py
|
|
153
|
+
|
|
154
|
+
# Environments
|
|
155
|
+
.env
|
|
156
|
+
.envrc
|
|
157
|
+
.venv
|
|
158
|
+
env/
|
|
159
|
+
venv/
|
|
160
|
+
ENV/
|
|
161
|
+
env.bak/
|
|
162
|
+
venv.bak/
|
|
163
|
+
|
|
164
|
+
# Spyder project settings
|
|
165
|
+
.spyderproject
|
|
166
|
+
.spyproject
|
|
167
|
+
|
|
168
|
+
# Rope project settings
|
|
169
|
+
.ropeproject
|
|
170
|
+
|
|
171
|
+
# mkdocs documentation
|
|
172
|
+
/site
|
|
173
|
+
|
|
174
|
+
# mypy
|
|
175
|
+
.mypy_cache/
|
|
176
|
+
.dmypy.json
|
|
177
|
+
dmypy.json
|
|
178
|
+
|
|
179
|
+
# Pyre type checker
|
|
180
|
+
.pyre/
|
|
181
|
+
|
|
182
|
+
# pytype static type analyzer
|
|
183
|
+
.pytype/
|
|
184
|
+
|
|
185
|
+
# Cython debug symbols
|
|
186
|
+
cython_debug/
|
|
187
|
+
|
|
188
|
+
# PyCharm
|
|
189
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
190
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
191
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
192
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
193
|
+
# .idea/
|
|
194
|
+
|
|
195
|
+
# Abstra
|
|
196
|
+
# Abstra is an AI-powered process automation framework.
|
|
197
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
198
|
+
# Learn more at https://abstra.io/docs
|
|
199
|
+
.abstra/
|
|
200
|
+
|
|
201
|
+
# Visual Studio Code
|
|
202
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
203
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
204
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
205
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
206
|
+
# .vscode/
|
|
207
|
+
# Temporary file for partial code execution
|
|
208
|
+
tempCodeRunnerFile.py
|
|
209
|
+
|
|
210
|
+
# Ruff stuff:
|
|
211
|
+
.ruff_cache/
|
|
212
|
+
|
|
213
|
+
# PyPI configuration file
|
|
214
|
+
.pypirc
|
|
215
|
+
|
|
216
|
+
# Marimo
|
|
217
|
+
marimo/_static/
|
|
218
|
+
marimo/_lsp/
|
|
219
|
+
__marimo__/
|
|
220
|
+
|
|
221
|
+
# Streamlit
|
|
222
|
+
.streamlit/secrets.toml
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Workflow
|
|
4
|
+
|
|
5
|
+
After completing each task: `ruff check .` + `pytest` green, then commit with
|
|
6
|
+
a short descriptive title and all details in the commit body.
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
| Command | What |
|
|
11
|
+
|---------|------|
|
|
12
|
+
| `uv run pytest` | all tests |
|
|
13
|
+
| `uv run pytest -v` | verbose |
|
|
14
|
+
| `uv run pytest tests/test_crud.py::test_symbol_crud` | single test |
|
|
15
|
+
| `uv run memos index --path . --full` | index project at path |
|
|
16
|
+
| `uv run memos query symbol <name> [--kind KIND]` | find symbols by name |
|
|
17
|
+
| `uv run memos query calls <name> [--direction callers\|callees]` | find callers/callees |
|
|
18
|
+
| `uv run memos query module <path>` | show everything for a file |
|
|
19
|
+
| `uv run memos serve --path . --port 8000` | start FastAPI server |
|
|
20
|
+
| `uv run memos serve-mcp --path .` | start MCP server (stdio) |
|
|
21
|
+
| `uv run pytest tests/test_mcp.py` | MCP server tests |
|
|
22
|
+
| `uv run pytest tests/test_llm_summary.py` | LLM summary tests |
|
|
23
|
+
| `uv run pytest tests/test_impact.py` | Impact analysis tests |
|
|
24
|
+
| `uv run pytest tests/test_hygiene.py` | Dead code / hygiene tests |
|
|
25
|
+
| `uv run pytest tests/test_dependency_graph.py` | Dependency graph tests |
|
|
26
|
+
| `uv run pytest tests/test_memory_hygiene.py` | Memory search & prune tests |
|
|
27
|
+
| `uv run pytest tests/test_reindex.py` | Reindex tool tests |
|
|
28
|
+
| `curl http://localhost:8000/symbols/{id}/context` | API: get context for symbol |
|
|
29
|
+
| `uv add <pkg>` | add dependency |
|
|
30
|
+
| `uv add --dev <pkg>` | add dev dependency |
|
|
31
|
+
| `uv sync` | reinstall after pyproject.toml changes |
|
|
32
|
+
|
|
33
|
+
## Layout
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
memos/
|
|
37
|
+
core/
|
|
38
|
+
db.py # get_connection(WAL+FK), run_migrations, CRUD (all return pydantic models), resolve_call_edges
|
|
39
|
+
models.py # Project, File, Symbol, CallEdge, Import, MemoryEntry
|
|
40
|
+
schema.sql # human-readable DDL copy
|
|
41
|
+
migrations/
|
|
42
|
+
0001_init.sql # authoritative DDL
|
|
43
|
+
0002_vec.sql
|
|
44
|
+
0003_prompt_version.sql
|
|
45
|
+
0004_memory_fts.sql
|
|
46
|
+
indexer/
|
|
47
|
+
base.py # LanguageIndexer ABC + ParsedSymbol/Call/Import/Result dataclasses
|
|
48
|
+
typescript.py # TypeScriptIndexer (tree-sitter, handles .ts + .tsx)
|
|
49
|
+
go.py # GoIndexer (tree-sitter, export by name case)
|
|
50
|
+
diff.py # compute_file_hash, should_reindex
|
|
51
|
+
query/
|
|
52
|
+
core.py # find_symbol, find_calls, get_module, find_calls_by_id, semantic_search,
|
|
53
|
+
# list_files, list_symbols, get_or_generate_summary, get_context,
|
|
54
|
+
# get_rename_impact, get_diff_impact, find_unused_symbols, find_dead_imports,
|
|
55
|
+
# get_dependency_graph, find_import_cycles, memory_search, memory_prune
|
|
56
|
+
# — pure query layer over db
|
|
57
|
+
api/
|
|
58
|
+
main.py # FastAPI app — thin adapter over query/core.py
|
|
59
|
+
schemas.py # pydantic response models for API
|
|
60
|
+
mcp/
|
|
61
|
+
server.py # MCP server (FastMCP, stdio) — thin adapter over query/core.py
|
|
62
|
+
search/
|
|
63
|
+
base.py # EmbeddingModel + VectorStore ABCs
|
|
64
|
+
embeddings.py # FastEmbedEmbedding (all-MiniLM-L6-v2, 384-dim)
|
|
65
|
+
sqlite_vec_store.py # SqliteVecStore (sqlite-vec vec0 table)
|
|
66
|
+
cli/
|
|
67
|
+
main.py # argparse: "memos index [--path .] [--full] [--no-embed]"
|
|
68
|
+
# "memos query (symbol|calls|module)"
|
|
69
|
+
# "memos serve [--path] [--port]"
|
|
70
|
+
# "memos serve-mcp [--path]"
|
|
71
|
+
tests/
|
|
72
|
+
conftest.py # fixture: in-memory sqlite with migrations applied
|
|
73
|
+
test_schema.py # table existence checks
|
|
74
|
+
test_crud.py # CRUD + cascade delete
|
|
75
|
+
test_migrations.py# idempotent re-run
|
|
76
|
+
test_typescript_indexer.py # 18 unit tests on TS parsing
|
|
77
|
+
test_go_indexer.py # 18 unit tests on Go parsing
|
|
78
|
+
test_cli_index.py # 8 integration tests: index flow (TS + Go)
|
|
79
|
+
test_resolver.py # 7 unit tests on call-edge resolution
|
|
80
|
+
test_query.py # 12 unit tests on query/core.py
|
|
81
|
+
test_cli_query.py # 7 integration tests: query flow (TS + Go)
|
|
82
|
+
test_api.py # 7 integration tests: FastAPI endpoints
|
|
83
|
+
test_mcp.py # 15 tests: MCP server tools
|
|
84
|
+
test_semantic_search.py # 8 tests: VecStore CRUD + semantic_search query
|
|
85
|
+
test_llm_summary.py # 11 tests: get_or_generate_summary, get_context, source_hash
|
|
86
|
+
test_impact.py # 8 tests: rename_impact, diff_impact
|
|
87
|
+
test_hygiene.py # 8 tests: unused symbols, dead imports
|
|
88
|
+
test_dependency_graph.py # 8 tests: dependency graph + cycle detection
|
|
89
|
+
test_memory_hygiene.py # 9 tests: memory search + prune
|
|
90
|
+
test_reindex.py # 3 tests: reindex_file_tool
|
|
91
|
+
test_migrations.py # 2 tests: idempotent re-run
|
|
92
|
+
fixtures/
|
|
93
|
+
typescript_mini/src/ # 3 .ts files for integration testing
|
|
94
|
+
go_mini/src/ # 3 .go files for integration testing
|
|
95
|
+
import_cycle/src/ # 2 .ts files with circular import
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Dependencies
|
|
99
|
+
|
|
100
|
+
- **pydantic** — all CRUD returns models, not raw rows
|
|
101
|
+
- **tree-sitter + tree-sitter-typescript + tree-sitter-go** — AST parsing (.ts, .tsx, .go)
|
|
102
|
+
- **stdlib sqlite3** — connection mgmt, WAL journal, FK enforcement
|
|
103
|
+
- **fastapi + uvicorn** — HTTP API
|
|
104
|
+
- **mcp[cli]** — MCP server (FastMCP, stdio transport)
|
|
105
|
+
- **fastembed** — ONNX embeddings (all-MiniLM-L6-v2, 384-dim)
|
|
106
|
+
- **sqlite-vec** — vector search extension for sqlite
|
|
107
|
+
- **rich** — CLI progress bars
|
|
108
|
+
- **pytest** (dev)
|
|
109
|
+
- **httpx** (dev, for TestClient)
|
|
110
|
+
- **pytest-anyio** (dev, for async MCP tests)
|
|
111
|
+
- **hatchling** (build)
|
|
112
|
+
|
|
113
|
+
## Architecture conventions
|
|
114
|
+
|
|
115
|
+
- `indexer/typescript.py` produces plain dataclasses (`ParseResult`), not pydantic models — conversion happens in CLI when calling CRUD
|
|
116
|
+
- `cli/main.py` is a thin argparse wrapper over `indexer/` + `core/db.py`; no business logic in CLI
|
|
117
|
+
- `query/core.py` has no knowledge of CLI, API, or MCP — all three are thin adapters over it
|
|
118
|
+
- `mcp/server.py` is a thin FastMCP wrapper over `query/core.py`; same pattern as `api/main.py`
|
|
119
|
+
- All MCP tools return JSON strings (parsable by the LLM), never raw text
|
|
120
|
+
- `index_file()` in cli/main.py is the unit of change: delete old → parse → insert new
|
|
121
|
+
- `memos index` stores DB at `{project_root}/.memos/memory.db`
|
|
122
|
+
- call_edges are inserted with `callee_symbol_id=NULL` (first pass); resolution is Task 5
|
|
123
|
+
- `callee_symbol_id` and `resolved_file_id` use `ON DELETE SET NULL` — when a callee symbol is deleted (e.g. during reindex), the FK is automatically nulled, then re-resolved in the second pass
|
|
124
|
+
- `export` keyword detection (TS): `export_statement` wraps declarations; the walker passes `exported=True` to children
|
|
125
|
+
- Go export: determined by `name[0].isupper()` — no `export_statement`
|
|
126
|
+
- Go methods: `method_declaration` nodes are separate from type declarations; receiver type is extracted from `receiver` field
|
|
127
|
+
- Go imports: both single `import "x"` and grouped `import ( "x" "y" )` forms are handled via `import_spec` / `import_spec_list`
|
|
128
|
+
|
|
129
|
+
## What does not exist yet
|
|
130
|
+
|
|
131
|
+
- Type checking, codegen — none configured
|
|
132
|
+
|
|
133
|
+
## Execution order (from spec §6)
|
|
134
|
+
|
|
135
|
+
1. ✅ `core/db.py` + `models.py` + `schema.sql` + migrations + tests
|
|
136
|
+
2. ✅ `indexer/base.py` + `indexer/typescript.py` + CLI `index`
|
|
137
|
+
3. ✅ `indexer/go.py`
|
|
138
|
+
4. ✅ `query/core.py` (find_symbol, find_calls, get_module) + CLI `query`
|
|
139
|
+
5. ✅ Call-edge resolution (second pass) + cross-file tests
|
|
140
|
+
6. ✅ FastAPI wrapper
|
|
141
|
+
7. ✅ Semantic search (sqlite-vec + sentence-transformers)
|
|
142
|
+
8. ✅ MCP server
|
|
143
|
+
9. ✅ `memory_entries` write-path via `memory_add_note`
|
|
144
|
+
10. ✅ LLM enrichment: `get_or_generate_summary()` with content_hash check, `get_context()` composite function
|
|
145
|
+
11. ✅ Section 0: Technical debt (dedup, batch resolve, SAVEPOINT, threading.Lock)
|
|
146
|
+
12. ✅ Section 1: Impact analysis (rename_impact, diff_impact, MCP, API, tests)
|
|
147
|
+
13. ✅ Section 2: Dead code / hygiene (unused symbols, dead imports, MCP, API, tests)
|
|
148
|
+
14. ✅ Section 3: Dependency graph (graph + cycle detection, MCP, API, tests)
|
|
149
|
+
15. ✅ Section 4: Memory search & hygiene (FTS5 search, prune, MCP, API, tests)
|
|
150
|
+
16. ✅ Section 5: Reindex file tool (per-file reindex via MCP, tests)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# AGENTS.md — memos navigation policy
|
|
2
|
+
|
|
3
|
+
> Скопируйте этот блок в `AGENTS.md` (или `CLAUDE.md` / `.opencode/instructions`,
|
|
4
|
+
> в зависимости от того, каким агентом вы пользуетесь) в корне вашего проекта.
|
|
5
|
+
> Если файл уже существует — добавьте это как отдельную секцию, не заменяйте
|
|
6
|
+
> весь файл. Замените `<project-root>` реальным путём, если ваш агент не умеет
|
|
7
|
+
> резолвить относительные пути сам.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Code navigation policy (memos)
|
|
12
|
+
|
|
13
|
+
Этот проект проиндексирован `memos` — структурным индексом кода (symbols,
|
|
14
|
+
call edges, imports) с episodic memory. Инструмент доступен через MCP-тулы.
|
|
15
|
+
**Прежде чем читать файл целиком или делать grep по коду — используй memos.**
|
|
16
|
+
Это быстрее, точнее и не тратит контекст на нерелевантные строки.
|
|
17
|
+
|
|
18
|
+
### Обязательный порядок действий
|
|
19
|
+
|
|
20
|
+
1. **В начале сессии**, если ещё не открыт проект — вызови `open_project`
|
|
21
|
+
с абсолютным путём к корню репозитория. Это одноразовое действие на
|
|
22
|
+
сессию, если проект уже открыт — не вызывай повторно.
|
|
23
|
+
|
|
24
|
+
2. **Чтобы найти определение функции/класса/переменной** — используй
|
|
25
|
+
`find_symbol_tool(name, kind=None, file_path=None)`.
|
|
26
|
+
Не используй `grep`/`cat` для этого — memos даёт точный результат
|
|
27
|
+
(файл, строки, сигнатура, exported) без ложных совпадений по имени
|
|
28
|
+
в комментариях/строках.
|
|
29
|
+
|
|
30
|
+
3. **Чтобы понять, кто вызывает функцию или что вызывает она** — используй
|
|
31
|
+
`find_calls_tool(symbol_name, direction="callers"|"callees")`.
|
|
32
|
+
Это заменяет ручной grep по имени функции во всём репозитории.
|
|
33
|
+
|
|
34
|
+
4. **Перед тем как редактировать функцию** — вызови `get_context_tool(symbol_id)`.
|
|
35
|
+
Он возвращает символ + всех callers + callees + episodic memory заметки +
|
|
36
|
+
кэшированный LLM-summary (если есть). **Это заменяет повторное чтение
|
|
37
|
+
всего файла и всех зависимых файлов** — не открывай их вручную, если
|
|
38
|
+
`get_context_tool` уже дал нужную картину.
|
|
39
|
+
|
|
40
|
+
5. **Чтобы посмотреть всё содержимое файла структурно** (какие символы,
|
|
41
|
+
вызовы, импорты) — используй `get_module_tool(path)` вместо чтения
|
|
42
|
+
файла целиком, если тебе не нужен именно raw-текст (форматирование,
|
|
43
|
+
комментарии, точный синтаксис для правки).
|
|
44
|
+
|
|
45
|
+
6. **Для поиска по смыслу, а не по точному имени** ("где у нас логика
|
|
46
|
+
авторизации", "функция, которая парсит даты") — используй
|
|
47
|
+
`semantic_search_tool(query, top_k)`.
|
|
48
|
+
|
|
49
|
+
7. **После значимого решения, вывода или "гочи"**, которое стоит помнить
|
|
50
|
+
в будущих сессиях (архитектурное решение, причина странного кода,
|
|
51
|
+
TODO с контекстом) — сохрани заметку через `memory_add_note(content,
|
|
52
|
+
scope_type, scope_id, kind)`. Не полагайся только на свой ответ в чате —
|
|
53
|
+
он не переживёт сессию, а memory_entries переживают.
|
|
54
|
+
|
|
55
|
+
8. **Перед началом работы с заметками** — вызови `get_memories(scope_type,
|
|
56
|
+
scope_id)`, чтобы узнать, что уже известно про этот файл/символ/проект
|
|
57
|
+
из прошлых сессий, прежде чем исследовать заново.
|
|
58
|
+
|
|
59
|
+
### Когда grep/cat/read_file всё-таки уместны
|
|
60
|
+
|
|
61
|
+
- Файл ещё не проиндексирован (новый, не .ts/.tsx/.go — расширения см. ниже)
|
|
62
|
+
или недавно создан и явно устарел в индексе
|
|
63
|
+
- Нужен именно raw-текст: точное форматирование, конкретные комментарии,
|
|
64
|
+
импорты в исходном виде для правки строки
|
|
65
|
+
- `find_symbol_tool`/`semantic_search_tool` не нашли ничего релевантного —
|
|
66
|
+
тогда grep как fallback, но перепроверь опечатки в имени символа сначала
|
|
67
|
+
|
|
68
|
+
### Что НЕ делать
|
|
69
|
+
|
|
70
|
+
- Не грепай по имени функции, чтобы найти её вызовы — используй
|
|
71
|
+
`find_calls_tool`. Grep даёт ложные совпадения (комментарии, строки,
|
|
72
|
+
похожие имена в других scope) и не различает caller/callee направление.
|
|
73
|
+
- Не читай весь файл, чтобы понять один символ — `get_context_tool` уже
|
|
74
|
+
дал тебе минимально достаточный контекст.
|
|
75
|
+
- Не забывай `open_project`, если сессия началась с чистого MCP-сервера —
|
|
76
|
+
без этого все остальные тулы вернут ошибку "no project open".
|
|
77
|
+
- Не дублируй информацию, которая уже есть в `get_memories` — сначала
|
|
78
|
+
проверь память, потом исследуй заново.
|
|
79
|
+
|
|
80
|
+
### Available tools cheat sheet
|
|
81
|
+
|
|
82
|
+
| Tool | Когда использовать |
|
|
83
|
+
|------|---------------------|
|
|
84
|
+
| `open_project(path)` | В начале сессии, один раз на проект |
|
|
85
|
+
| `find_symbol_tool(name, kind?, file_path?)` | Найти определение символа по имени |
|
|
86
|
+
| `find_calls_tool(symbol_name, direction)` | Callers или callees символа |
|
|
87
|
+
| `get_module_tool(path)` | Всё содержимое файла структурно |
|
|
88
|
+
| `get_context_tool(symbol_id)` | Полный контекст перед правкой функции |
|
|
89
|
+
| `rename_impact_tool(symbol_id)` | Анализ последствий переименования символа |
|
|
90
|
+
| `diff_impact_tool(path)` | Анализ blast radius exported-символов файла |
|
|
91
|
+
| `semantic_search_tool(query, top_k?)` | Поиск по смыслу, не по точному имени |
|
|
92
|
+
| `list_files_tool(path_filter?)` | Список индексированных файлов |
|
|
93
|
+
| `list_symbols_tool(file_path?, kind?)` | Список индексированных символов |
|
|
94
|
+
| `list_projects_tool()` | Инфо и статистика по текущему проекту |
|
|
95
|
+
| `memory_add_note(content, scope_type, scope_id?, kind?)` | Сохранить заметку/решение |
|
|
96
|
+
| `get_memories(scope_type?, scope_id?)` | Прочитать заметки из прошлых сессий |
|
|
97
|
+
| `find_unused_symbols_tool()` | Найти неиспользуемые private функции |
|
|
98
|
+
| `find_dead_imports_tool()` | Найти неразрешившиеся импорты |
|
|
99
|
+
| `get_dependency_graph_tool()` | Граф зависимостей между файлами |
|
|
100
|
+
| `find_import_cycles_tool()` | Найти циклы в импортах |
|
|
101
|
+
| `memory_search_tool(query, top_k?)` | Полнотекстовый поиск по memory entries |
|
|
102
|
+
| `memory_prune_tool(older_than_days?, kind?, apply?)` | Удаление устаревших записей (dry-run по умолчанию) |
|
|
103
|
+
| `reindex_file_tool(path)` | Переиндексировать один файл после правки |
|
|
104
|
+
|
|
105
|
+
Индексируются файлы с расширениями `.ts`, `.tsx`, `.go`. Индекс лежит в
|
|
106
|
+
`.memos/memory.db` в корне проекта и обновляется через `memos index --path .`
|
|
107
|
+
(инкрементально, по content hash — быстро на повторных запусках). Для
|
|
108
|
+
переиндексации одного файла после правки используй `reindex_file_tool(path)`
|
|
109
|
+
— это быстрее и дешевле полного прохода.
|
|
110
|
+
|
|
111
|
+
Если каких-то тулов из таблицы нет в твоём MCP-клиенте — значит memos ещё
|
|
112
|
+
не переиндексирован для этого проекта или сервер не запущен: запусти
|
|
113
|
+
`memos serve-mcp` и настрой подключение согласно README проекта memos.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-07-21
|
|
4
|
+
|
|
5
|
+
- Initial release
|
|
6
|
+
- TypeScript/Go structural index via tree-sitter
|
|
7
|
+
- MCP server with 20 tools
|
|
8
|
+
- FastAPI with 15 endpoints
|
|
9
|
+
- Semantic search (fastembed + sqlite-vec)
|
|
10
|
+
- Episodic memory (FTS5)
|
|
11
|
+
- Impact analysis, dead code, dependency graph, memory hygiene
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TAskMAster339
|
|
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.
|