minder-cli 0.3.6__tar.gz → 0.4.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.
- {minder_cli-0.3.6 → minder_cli-0.4.0}/PKG-INFO +57 -41
- {minder_cli-0.3.6 → minder_cli-0.4.0}/pyproject.toml +2 -2
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/commands/update.py +7 -7
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/utils/version.py +15 -2
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/repo_scanner.py +38 -41
- {minder_cli-0.3.6 → minder_cli-0.4.0}/.gitignore +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/LICENSE +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/README-pypi.md +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/README.md +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/api/routers/prompts.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/application/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/application/admin/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/application/admin/dto.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/application/admin/jobs.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/application/admin/use_cases.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/context.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/middleware.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/principal.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/rate_limiter.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/rbac.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/auth/service.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/bootstrap/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/bootstrap/providers.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/bootstrap/transport.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/cache/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/cache/providers.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/chunking/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/chunking/code_splitter.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/chunking/splitter.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/cli.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/config.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/continuity.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/dev.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/embedding/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/embedding/base.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/embedding/local.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/embedding/openai.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/edges.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/executor.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/graph.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/evaluator.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/guard.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/llm.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/planning.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/reasoning.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/reranker.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/retriever.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/verification.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/nodes/workflow_planner.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/runtime.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/graph/state.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/llm/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/llm/base.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/llm/factory.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/llm/litert.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/llm/openai.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/base.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/client.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/document.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/error.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/graph.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/history.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/job.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/prompt.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/repository.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/rule.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/session.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/skill.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/user.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/models/workflow.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/observability/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/observability/audit.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/observability/logging.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/observability/metrics.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/observability/tracing.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/commands/auth.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/commands/ide.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/commands/mcp.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/commands/sync.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/main.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/utils/common.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/utils/config.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/cli/utils/git.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/api.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/context.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/dashboard.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/jobs.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/memories.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/prompts.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/routes.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/runtime.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/search.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/presentation/http/admin/skills.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/prompts/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/prompts/formatter.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/resources/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/retrieval/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/retrieval/hybrid.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/retrieval/mmr.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/retrieval/multi_hop.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/runtime.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/server.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/document.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/error.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/feedback.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/graph.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/history.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/interfaces.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/milvus/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/milvus/client.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/milvus/collections.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/milvus/vector_store.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/mongodb/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/mongodb/client.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/mongodb/indexes.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/mongodb/operational_store.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/relational.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/repo_state.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/rule.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/store/vector.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/auth.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/graph.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/ingest.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/memory.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/query.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/registry.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/search.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/session.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/skills.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/tools/workflow.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/transport/__init__.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/transport/base.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/transport/sse.py +0 -0
- {minder_cli-0.3.6 → minder_cli-0.4.0}/src/minder/transport/stdio.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: minder-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Minder CLI is the command-line interface for the Minder self-hosted MCP platform.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hiimtrung/minder
|
|
6
6
|
Project-URL: Repository, https://github.com/hiimtrung/minder
|
|
@@ -37,83 +37,99 @@ Requires-Dist: zipp>=3.21.0; extra == 'server'
|
|
|
37
37
|
Requires-Dist: zstandard>=0.25.0; extra == 'server'
|
|
38
38
|
Description-Content-Type: text/markdown
|
|
39
39
|
|
|
40
|
-
#
|
|
40
|
+
# Minder
|
|
41
41
|
|
|
42
42
|
[](https://pypi.org/project/minder-cli/)
|
|
43
43
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
44
44
|
|
|
45
|
-
**
|
|
45
|
+
**Minder** is a self-hosted MCP (Model Context Protocol) platform for repository-aware engineering intelligence.
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
It combines a local-first inference stack, a persistent memory and workflow engine, and a developer-facing CLI into a single deployable unit.
|
|
48
48
|
|
|
49
|
-
##
|
|
49
|
+
## What's in this repo
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
| Component | Description |
|
|
52
|
+
|-----------|-------------|
|
|
53
|
+
| **Minder Server** | MCP gateway — SSE + stdio transport, RAG pipeline, workflow engine, memory, admin HTTP |
|
|
54
|
+
| **Minder CLI** (`minder-cli` on PyPI) | Edge CLI — IDE scaffold, repo sync, login, self-update |
|
|
55
|
+
| **Minder Dashboard** | Astro admin console — client management, onboarding, skill catalog |
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
pipx install minder-cli
|
|
57
|
-
```
|
|
57
|
+
## Architecture
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
```
|
|
60
|
+
Developer → minder-cli → Minder Server ←→ AI agents (Codex / Copilot / Claude)
|
|
61
|
+
│
|
|
62
|
+
┌──────────────┼──────────────┐
|
|
63
|
+
│ │ │
|
|
64
|
+
MongoDB Redis Milvus
|
|
65
|
+
(graph/memory) (cache) (vector search)
|
|
66
|
+
│
|
|
67
|
+
┌─────┴──────┐
|
|
68
|
+
│ │
|
|
69
|
+
LiteRT-LM FastEmbed
|
|
70
|
+
(LLM gen) (embedding)
|
|
71
|
+
```
|
|
60
72
|
|
|
61
|
-
|
|
73
|
+
- **LLM inference**: LiteRT-LM (Google AI Edge) — on-device, hardware-accelerated, no HTTP overhead
|
|
74
|
+
- **Embedding inference**: FastEmbed running natively in-process (`mxbai-embed-large-v1`) — zero-dependency ONNX acceleration
|
|
62
75
|
|
|
63
76
|
## Quick Start
|
|
64
77
|
|
|
65
|
-
###
|
|
78
|
+
### Run the server
|
|
66
79
|
|
|
67
80
|
```bash
|
|
68
|
-
|
|
81
|
+
# 1. Download the LiteRT-LM model
|
|
82
|
+
./scripts/download_models.sh
|
|
83
|
+
|
|
84
|
+
# 2. Start infra (MongoDB + Redis + Milvus)
|
|
85
|
+
docker compose -f docker/docker-compose.local.yml up -d
|
|
86
|
+
|
|
87
|
+
# 3. Run Minder Server
|
|
88
|
+
uv run python -m minder.server
|
|
69
89
|
```
|
|
70
90
|
|
|
71
|
-
|
|
91
|
+
Or use the one-command release installer (Docker only, no local uv needed):
|
|
72
92
|
|
|
73
93
|
```bash
|
|
74
|
-
|
|
75
|
-
minder install-ide --target vscode --target claude-code
|
|
94
|
+
curl -fsSL https://raw.githubusercontent.com/hiimtrung/minder/main/scripts/release/install-minder-release.sh | bash
|
|
76
95
|
```
|
|
77
96
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
### 3. Sync a repository
|
|
97
|
+
### Connect the CLI
|
|
81
98
|
|
|
82
99
|
```bash
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
# Install
|
|
101
|
+
uv tool install minder-cli
|
|
85
102
|
|
|
86
|
-
|
|
103
|
+
# Log in with your client key
|
|
104
|
+
minder login --client-key mkc_your_key --server-url http://localhost:8800/sse
|
|
87
105
|
|
|
88
|
-
|
|
106
|
+
# Set up IDE integration (VS Code, Cursor, Claude Code)
|
|
107
|
+
minder install-ide --target vscode --target claude-code
|
|
89
108
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
| `minder install-ide` | Scaffold MCP assets for VS Code / Cursor / Claude Code |
|
|
94
|
-
| `minder sync` | Index a repository into the Minder Server |
|
|
95
|
-
| `minder check-update` | Check for available CLI and server updates |
|
|
96
|
-
| `minder self-update` | Update CLI or server in place |
|
|
109
|
+
# Sync a repository
|
|
110
|
+
minder sync --repo-id <uuid>
|
|
111
|
+
```
|
|
97
112
|
|
|
98
|
-
## MCP Tools
|
|
113
|
+
## MCP Tools
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
When connected, Minder exposes these tools to your AI agents:
|
|
101
116
|
|
|
102
117
|
| Tool | Description |
|
|
103
118
|
|------|-------------|
|
|
104
119
|
| `minder_query` | Full RAG pipeline: retrieve → reason → verify → respond |
|
|
105
|
-
| `minder_search_code` | Semantic code search across indexed
|
|
120
|
+
| `minder_search_code` | Semantic code search across indexed repos |
|
|
106
121
|
| `minder_memory_recall` | Retrieve persisted engineering memory |
|
|
107
122
|
| `minder_workflow_get` | Read current workflow state |
|
|
108
123
|
| `minder_session_restore` | Restore session continuity across context windows |
|
|
109
124
|
|
|
110
|
-
##
|
|
125
|
+
## Documentation
|
|
111
126
|
|
|
112
|
-
- [
|
|
113
|
-
- [Server Setup
|
|
114
|
-
- [Local Dev Setup](
|
|
115
|
-
- [
|
|
127
|
+
- [System Design](docs/system-design.md)
|
|
128
|
+
- [Server Setup](docs/minder-server.md)
|
|
129
|
+
- [Local Dev Setup](docs/guides/local-setup.md)
|
|
130
|
+
- [Production Deployment](docs/guides/production-deployment.md)
|
|
131
|
+
- [Admin & Client Onboarding](docs/guides/admin-client-onboarding.md)
|
|
116
132
|
|
|
117
133
|
## License
|
|
118
134
|
|
|
119
|
-
Apache License 2.0. See [LICENSE](
|
|
135
|
+
Apache License 2.0. See [LICENSE](LICENSE) for details.
|
|
@@ -4,9 +4,9 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "minder-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Minder CLI is the command-line interface for the Minder self-hosted MCP platform."
|
|
9
|
-
readme = "README
|
|
9
|
+
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.14"
|
|
11
11
|
keywords = ["mcp", "cli", "ai", "code-search", "workflow"]
|
|
12
12
|
classifiers = [
|
|
@@ -35,7 +35,7 @@ def version_command(args: argparse.Namespace) -> int:
|
|
|
35
35
|
else:
|
|
36
36
|
print(" status: up to date")
|
|
37
37
|
else:
|
|
38
|
-
print("minder version unknown (not installed as a package)")
|
|
38
|
+
print("minder-cli version unknown (not installed as a package)")
|
|
39
39
|
return 0
|
|
40
40
|
|
|
41
41
|
|
|
@@ -109,15 +109,15 @@ def check_update_command(args: argparse.Namespace) -> int:
|
|
|
109
109
|
|
|
110
110
|
def _cli_update_commands(manager: str) -> list[list[str]]:
|
|
111
111
|
if manager == "uv":
|
|
112
|
-
return [["uv", "tool", "upgrade", "minder"]]
|
|
112
|
+
return [["uv", "tool", "upgrade", "minder-cli"]]
|
|
113
113
|
if manager == "pipx":
|
|
114
|
-
return [["pipx", "upgrade", "minder"]]
|
|
114
|
+
return [["pipx", "upgrade", "minder-cli"]]
|
|
115
115
|
if manager == "pip":
|
|
116
|
-
return [[sys.executable, "-m", "pip", "install", "--upgrade", "minder"]]
|
|
116
|
+
return [[sys.executable, "-m", "pip", "install", "--upgrade", "minder-cli"]]
|
|
117
117
|
return [
|
|
118
|
-
["uv", "tool", "upgrade", "minder"],
|
|
119
|
-
["pipx", "upgrade", "minder"],
|
|
120
|
-
[sys.executable, "-m", "pip", "install", "--upgrade", "minder"],
|
|
118
|
+
["uv", "tool", "upgrade", "minder-cli"],
|
|
119
|
+
["pipx", "upgrade", "minder-cli"],
|
|
120
|
+
[sys.executable, "-m", "pip", "install", "--upgrade", "minder-cli"],
|
|
121
121
|
]
|
|
122
122
|
|
|
123
123
|
|
|
@@ -6,11 +6,12 @@ from importlib.metadata import (
|
|
|
6
6
|
version as package_version,
|
|
7
7
|
)
|
|
8
8
|
|
|
9
|
+
from pathlib import Path
|
|
9
10
|
import httpx
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
13
|
-
_PYPI_JSON_URL = "https://pypi.org/pypi/minder/json"
|
|
14
|
+
_PYPI_JSON_URL = "https://pypi.org/pypi/minder-cli/json"
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def parse_version(raw_version: str) -> tuple[int, ...]:
|
|
@@ -26,8 +27,20 @@ def parse_version(raw_version: str) -> tuple[int, ...]:
|
|
|
26
27
|
|
|
27
28
|
def installed_package_version() -> str | None:
|
|
28
29
|
try:
|
|
29
|
-
return package_version("minder")
|
|
30
|
+
return package_version("minder-cli")
|
|
30
31
|
except PackageNotFoundError:
|
|
32
|
+
# Fallback for development mode: try to read from pyproject.toml
|
|
33
|
+
try:
|
|
34
|
+
# Look for pyproject.toml in the repo root (5 levels up from this file)
|
|
35
|
+
pyproject_path = Path(__file__).parents[5] / "pyproject.toml"
|
|
36
|
+
if pyproject_path.exists():
|
|
37
|
+
content = pyproject_path.read_text()
|
|
38
|
+
import re
|
|
39
|
+
match = re.search(r'^version\s*=\s*["\']([^"\']+)["\']', content, re.MULTILINE)
|
|
40
|
+
if match:
|
|
41
|
+
return match.group(1) + "-dev"
|
|
42
|
+
except Exception:
|
|
43
|
+
pass
|
|
31
44
|
return None
|
|
32
45
|
|
|
33
46
|
|
|
@@ -132,6 +132,7 @@ class RepoScanner:
|
|
|
132
132
|
self._git_metadata_cache: dict[str, dict[str, Any]] = {}
|
|
133
133
|
self._git_line_commit_cache: dict[tuple[str, int], dict[str, str] | None] = {}
|
|
134
134
|
self._git_commit_detail_cache: dict[str, dict[str, str]] = {}
|
|
135
|
+
self._git_file_blame_cache: dict[str, dict[int, str]] = {}
|
|
135
136
|
self._git_enabled = True
|
|
136
137
|
|
|
137
138
|
def _run_git(
|
|
@@ -280,6 +281,7 @@ class RepoScanner:
|
|
|
280
281
|
builder._git_metadata_cache = {}
|
|
281
282
|
builder._git_line_commit_cache = {}
|
|
282
283
|
builder._git_commit_detail_cache = {}
|
|
284
|
+
builder._git_file_blame_cache = {}
|
|
283
285
|
builder._git_enabled = True
|
|
284
286
|
|
|
285
287
|
service_dirs = builder._discover_service_boundaries()
|
|
@@ -374,24 +376,21 @@ class RepoScanner:
|
|
|
374
376
|
}
|
|
375
377
|
|
|
376
378
|
def _discover_service_boundaries(self) -> list[Path]:
|
|
377
|
-
service_dirs:
|
|
378
|
-
for
|
|
379
|
-
for
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
service_dirs.append(svc_dir)
|
|
385
|
-
return sorted(service_dirs, key=lambda path: len(path.parts), reverse=True)
|
|
379
|
+
service_dirs: set[Path] = set()
|
|
380
|
+
for path in self._root.rglob("*"):
|
|
381
|
+
if any(part.startswith(".") for part in path.parts):
|
|
382
|
+
continue
|
|
383
|
+
if path.is_file() and path.name in _SERVICE_MARKERS:
|
|
384
|
+
service_dirs.add(path.parent)
|
|
385
|
+
return sorted(list(service_dirs), key=lambda path: len(path.parts), reverse=True)
|
|
386
386
|
|
|
387
387
|
def _discover_source_files(self) -> list[Path]:
|
|
388
388
|
files: list[Path] = []
|
|
389
|
-
for
|
|
390
|
-
for
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
files.append(path)
|
|
389
|
+
for path in self._root.rglob("*"):
|
|
390
|
+
if any(part.startswith(".") or part == "__pycache__" for part in path.parts):
|
|
391
|
+
continue
|
|
392
|
+
if path.is_file() and path.suffix.lower() in _SOURCE_SUFFIXES:
|
|
393
|
+
files.append(path)
|
|
395
394
|
return sorted(set(files))
|
|
396
395
|
|
|
397
396
|
def _resolve_source_files(self, changed_files: list[str] | None) -> list[Path]:
|
|
@@ -579,34 +578,32 @@ class RepoScanner:
|
|
|
579
578
|
return commits
|
|
580
579
|
|
|
581
580
|
def _git_line_commit(self, rel_path: str, line_number: int) -> dict[str, str] | None:
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
581
|
+
if rel_path not in self._git_file_blame_cache:
|
|
582
|
+
result = self._run_git(["blame", "--line-porcelain", "--", rel_path], check=False)
|
|
583
|
+
if result.returncode != 0:
|
|
584
|
+
self._git_file_blame_cache[rel_path] = {}
|
|
585
|
+
else:
|
|
586
|
+
blame_data: dict[int, str] = {}
|
|
587
|
+
current_sha = None
|
|
588
|
+
for line in result.stdout.splitlines():
|
|
589
|
+
if not line:
|
|
590
|
+
continue
|
|
591
|
+
if current_sha is None:
|
|
592
|
+
current_sha = line.split(" ", 1)[0]
|
|
593
|
+
elif line.startswith("\t"):
|
|
594
|
+
# This line indicates the end of a porcelain block
|
|
595
|
+
current_sha = None
|
|
596
|
+
elif line.startswith("result-line "):
|
|
597
|
+
target_line = int(line.split(" ")[1])
|
|
598
|
+
if current_sha and set(current_sha) != {"0"}:
|
|
599
|
+
blame_data[target_line] = current_sha
|
|
600
|
+
self._git_file_blame_cache[rel_path] = blame_data
|
|
601
|
+
|
|
602
|
+
sha = self._git_file_blame_cache.get(rel_path, {}).get(line_number)
|
|
603
|
+
if not sha:
|
|
605
604
|
return None
|
|
606
605
|
|
|
607
|
-
|
|
608
|
-
self._git_line_commit_cache[cache_key] = details
|
|
609
|
-
return details
|
|
606
|
+
return self._git_commit_details(sha)
|
|
610
607
|
|
|
611
608
|
def _git_commit_details(self, sha: str) -> dict[str, str]:
|
|
612
609
|
cached = self._git_commit_detail_cache.get(sha)
|
|
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
|