mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-06-13 05:59:36 +00:00
chore: add nim mcp server and CLAUDE.md (#1441)
This commit is contained in:
parent
0ad13ca897
commit
b892379ff1
5
.claude/settings.json
Normal file
5
.claude/settings.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"env": {
|
||||
"MCP_TIMEOUT": "120000"
|
||||
}
|
||||
}
|
||||
217
.claude/skills/nim-mcp-tools/SKILL.md
Normal file
217
.claude/skills/nim-mcp-tools/SKILL.md
Normal file
@ -0,0 +1,217 @@
|
||||
---
|
||||
name: nim-mcp-tools
|
||||
description: 'Use for Nim symbol navigation, diagnostics, and type resolution. MANDATORY: Use specialized MCP tools (nimFindSymbols, nimFindReferences, nimListSymbols, nimCheckFile, nimCheckProject, nimFindTypeDefinition) first; fall back to grep only on error or user confirmation.'
|
||||
---
|
||||
|
||||
# Nim MCP Tools
|
||||
|
||||
## Core Mandate
|
||||
|
||||
AI agents MUST prefer specialized MCP tools over general-purpose instruments (grep, shell commands, `read_file` with manual parsing) for all Nim symbol-related and Nim diagnostics tasks. This is critical for:
|
||||
|
||||
1. **Token Efficiency**: MCP tools return structured, relevant data, avoiding large file reads or noisy grep outputs.
|
||||
2. **Precision**: These tools understand Nim semantics (scopes, imports, overloads) which string-based search cannot.
|
||||
|
||||
## Activation Rule
|
||||
|
||||
If the user asks to find, rename, remove, audit, update, standardize naming, or fix issues/project of a Nim symbol or its usages, this skill MUST be used first and the workflow must start with the Nim MCP symbol tools.
|
||||
|
||||
If the user asks to check a single Nim file for errors, warnings, hints, diagnostics, issues, problems, or compiler feedback, this skill MUST be used first and the workflow must start with `nimCheckFile`.
|
||||
|
||||
If the user asks to check a Nim project for errors, warnings, hints, diagnostics, issues, problems, compiler feedback, or to "fix" it, this skill MUST be used first and the workflow must start with `nimCheckProject`.
|
||||
|
||||
If the user asks to determine where a symbol comes from, what type it is, what its fields are (including private ones), or resolve a symbol's type definition, this skill MUST be used first and the workflow must start with `nimFindTypeDefinition`.
|
||||
|
||||
This applies to requests phrased as:
|
||||
|
||||
- "find all usages/references of `Foo`"
|
||||
- "remove all definitions of and references to `Foo`"
|
||||
- "rename `Foo` everywhere"
|
||||
- "standardize naming for `Foo`"
|
||||
- "fix casing for all variables"
|
||||
- "where is `Foo` defined?"
|
||||
- "list the symbols in this Nim file/module"
|
||||
- "check this file/module for errors"
|
||||
- "show diagnostics for `foo.nim`"
|
||||
- "check this project/workspace/repository/package for errors"
|
||||
- "fix issues in this project"
|
||||
- "fix the repo"
|
||||
- "find Nim diagnostics in the current codebase"
|
||||
- "show warnings and hints for this repo"
|
||||
- "scan the current module tree for Nim issues"
|
||||
- "what is the type of this symbol?"
|
||||
- "what module/package does this type come from?"
|
||||
- "what fields does this type have?"
|
||||
- "is this a type alias or a concrete type?"
|
||||
- "where is this type defined?"
|
||||
|
||||
Treat user wording such as **project**, **workspace**, **repository**, **repo**, **package**, **codebase**, **checkout**, and **module tree** as referring to the current Nim project context when they are asking for project-wide diagnostics.
|
||||
|
||||
Treat user wording such as **file**, **module** (when a concrete Nim file is identified), **source file**, and explicit `*.nim` paths as referring to single-file diagnostics when they are asking for diagnostics for one file.
|
||||
|
||||
Do **not** pair `nimFindSymbols`, `nimCheckFile`, or `nimCheckProject` with `grep`, `ripgrep`, or shell search "just to double-check". If the task is about a Nim symbol or Nim diagnostics, MCP tools own the search unless they have already failed.
|
||||
|
||||
## User Terminology vs MCP `kind`
|
||||
|
||||
Users may ask for symbol categories using looser or non-strict terminology. AI agents MUST map that wording to the exact Nim MCP `kind` values before filtering results from `nimListSymbols(...)` or `nimFindSymbols(...)`.
|
||||
|
||||
The MCP server returns Nim-oriented kind names derived from nimsuggest symbol kinds with the leading `sk` removed, such as `Const`, `EnumField`, `Field`, `Iterator`, `Converter`, `Let`, `Macro`, `Method`, `Proc`, `Template`, `Type`, `Var`, and `Func`.
|
||||
|
||||
Use these terminology mappings when interpreting user requests:
|
||||
|
||||
- **function** / **functions**: usually match `Func` and `Proc`
|
||||
- **pure function** / **pure functions**: match `Func`
|
||||
- **callable** / **routine**: may include `Func`, `Proc`, `Method`, `Iterator`, `Converter`, `Macro`, and `Template`
|
||||
- **class** / **classes**: match `Type`
|
||||
- **variable** / **variables**: match `Var` and `Let`
|
||||
- **property** / **properties**: match `Field`
|
||||
- **enum member** / **enum members**: match `EnumField`
|
||||
- **constant** / **constants**: match `Const`
|
||||
|
||||
Interpret user wording semantically, not literally. For example:
|
||||
|
||||
- "list all classes in this module" -> filter for `kind == Type`
|
||||
- "list all variables" -> filter for `kind in {Var, Let}`
|
||||
- "list all functions" -> filter for `kind in {Func, Proc}` unless the surrounding context clearly asks for all callables
|
||||
- "list all pure functions" -> filter for `kind == Func`
|
||||
|
||||
## When to Use
|
||||
|
||||
- **Finding References**: To rename a symbol, update a signature, or find usages.
|
||||
- **Symbol Discovery**: To find where a symbol is defined by name.
|
||||
- **Type Resolution**: To determine where a local symbol comes from (which module), what its type is, and what fields it has (including private ones). Uses `nimFindTypeDefinition(path, line, column)` on the symbol's cursor position.
|
||||
- **Naming Standardization**: To fix casing or follow style guides (e.g., standardizing to `camelCase`) across the project.
|
||||
- **Fixing Project Issues**: To iteratively find and resolve all diagnostics in the project.
|
||||
- **File Analysis**: To get an overview of all symbols in a file.
|
||||
- **File Diagnostics**: To check one specific Nim file for errors, warnings, and hints.
|
||||
- **Project Diagnostics**: To check the current Nim project/workspace/repository/package for errors, warnings, and hints.
|
||||
- **Debugging Type Mismatches**: When a diagnostic reveals a type mismatch, use `nimFindTypeDefinition` on both sides to understand what types are expected vs provided.
|
||||
- **Code Generation / Refactoring**: Before generating code that interacts with a type, find its definition to understand its structure and field layout.
|
||||
|
||||
## Workflows
|
||||
|
||||
### 1. Find All References or Usages of a Symbol Name
|
||||
|
||||
Do NOT grep for the name.
|
||||
|
||||
1. Call `nimFindSymbols(query: "SymbolName")` to get exact `path`, `line`, and `column`.
|
||||
2. For each relevant result, call `nimFindReferences(path, line, column)`.
|
||||
3. Aggregate the results.
|
||||
|
||||
Use this workflow for "usages", "references", "call sites", and cleanup requests such as removing all definitions of and references to a symbol.
|
||||
|
||||
### 2. List All Symbols in a File
|
||||
|
||||
Do NOT read the whole file to find definitions.
|
||||
|
||||
1. Call `nimListSymbols(path: "path/to/file.nim")`.
|
||||
2. If the user asked for a symbol category, filter by the MCP `kind` values that correspond to the user's terminology.
|
||||
3. Use the returned list to navigate or analyze the file structure.
|
||||
|
||||
### 3. Find Definitions
|
||||
|
||||
1. Call `nimFindSymbols(query: "query")`.
|
||||
|
||||
### 4. Resolve Type / Determine Origin of a Symbol
|
||||
|
||||
Use this when asked where a symbol comes from, what its type is, or to inspect its definition (fields, kind, etc.).
|
||||
|
||||
1. Call `nimFindTypeDefinition(path, line, column)` with the cursor positioned on the symbol of interest.
|
||||
2. The result contains the definition `path`, `line`, `column`, `name`, `type`, and `kind`.
|
||||
3. If the user needs to see the full definition (e.g., object fields), read the source at the returned path/line.
|
||||
4. Use this for requests like "what type is this variable?", "what module does this type come from?", "what fields does this object have?".
|
||||
|
||||
### 5. Debug Type Mismatch (Check + Type Definition)
|
||||
|
||||
Use this when fixing a diagnostic that involves a type mismatch.
|
||||
|
||||
1. Call `nimCheckFile(path)` to get the diagnostic with the exact error location.
|
||||
2. For the reported location, call `nimFindTypeDefinition(path, line, column)` on the involved symbols to understand what types are expected vs provided.
|
||||
3. Resolve the mismatch with the correct type or conversion.
|
||||
|
||||
### 6. Explore Object Structure (List Symbols + Type Definition)
|
||||
|
||||
Use this when asked to describe or document a type's shape.
|
||||
|
||||
1. Call `nimFindSymbols(query: "TypeName")` to locate the type definition.
|
||||
2. Call `nimFindTypeDefinition(path, line, column)` on the type name to confirm the definition location.
|
||||
3. Read the source at the definition location to enumerate all fields (including private ones) and their types.
|
||||
4. Optionally, call `nimFindTypeDefinition` on each field type to recursively resolve nested types.
|
||||
|
||||
### 7. Check a Single Nim File for Diagnostics
|
||||
|
||||
Do NOT approximate file diagnostics by reading the file manually or by running a project-wide diagnostic request when the user asked about one file.
|
||||
|
||||
1. Call `nimCheckFile(path: "path/to/file.nim")`.
|
||||
2. Treat the result as the answer unless the user explicitly asked for broader validation such as project-wide diagnostics, tests, or builds.
|
||||
3. Use the returned diagnostics to report errors, warnings, and hints for that file.
|
||||
4. If the user asked for only a subset (for example, only errors or only warnings), filter the returned diagnostics by severity before presenting them.
|
||||
|
||||
Use this workflow for requests phrased as checking a specific file, source file, module, or explicit `*.nim` path for Nim issues.
|
||||
|
||||
### 8. Check the Current Nim Project for Diagnostics
|
||||
|
||||
Do NOT approximate project diagnostics by grepping build logs or manually scanning files.
|
||||
|
||||
1. Call `nimCheckProject()`.
|
||||
2. Use the returned diagnostics to report errors, warnings, and hints for the current Nim project context.
|
||||
3. If the user asked for only a subset (for example, only errors or only warnings), filter the returned diagnostics by severity before presenting them.
|
||||
|
||||
Use this workflow for requests phrased as checking the current project, workspace, repository, repo, package, codebase, checkout, or module tree for Nim issues.
|
||||
|
||||
### 9. Standardize Naming
|
||||
|
||||
Use this when asked to fix casing, follow a style guide, or rename symbols to the standard `camelCase` (as per standard Nim convention).
|
||||
|
||||
1. Iterate through the project files one by one.
|
||||
2. For each file, call `nimListSymbols(path: "path/to/file.nim")` to retrieve the symbols that need to be standardized.
|
||||
3. For each symbol found, call `nimFindReferences(path, line, column)` to identify all of its usages and call sites across the project.
|
||||
4. Standardize the definition and all identified reference sites to `camelCase` to ensure consistency and adherence to Nim's standard style.
|
||||
5. After a file has been processed, call `nimCheckFile(path: "path/to/file.nim")` to verify that the changes are correct and no errors were introduced.
|
||||
|
||||
### 10. Fix Project Issues
|
||||
|
||||
Use this when asked to "fix issues", "fix project", or "fix the repo".
|
||||
|
||||
1. Call `nimCheckProject()` to find all diagnostics in the project.
|
||||
2. Analyze the diagnostics and resolve the identified issues.
|
||||
3. Repeat steps 1 and 2 until `nimCheckProject()` returns no more issues.
|
||||
4. **Limit**: If issues remain after 3 iterations, you MUST stop and prompt the user, asking if they would like you to continue.
|
||||
5. **Post-Fix Step**: Once all issues are resolved (or the user stops the process), ask the user if they would like you to check for naming consistency.
|
||||
6. **Consistency Check**: If the user agrees, use `nimFindSymbols` and `nimFindReferences` to find all variations of symbol usage in the project.
|
||||
7. **Standardization Prompt**: Prompt the user if they would like to standardize naming based on the findings.
|
||||
|
||||
## Fallback Policy
|
||||
|
||||
Specialized Nim MCP tools are the primary instrument. General-purpose tools (grep, ripgrep, shell commands) are secondary and their use is governed by the following rules:
|
||||
|
||||
1. **On Error**: If an MCP tool fails due to a technical error (e.g., tool crash, timeout, connection issue), you MUST fall back to `grep_search` or other general-purpose tools to fulfill the request.
|
||||
- State clearly that the MCP tool failed.
|
||||
- Use the narrowest fallback necessary.
|
||||
2. **On Empty Results**: If an MCP tool returns no results (empty list), do NOT automatically fall back to grep. Instead, you MUST prompt the user, asking if they would like you to attempt a plain text search using general-purpose tools.
|
||||
3. **Availability**: If MCP tools are unavailable in the environment, use general-purpose tools but inform the user.
|
||||
|
||||
When falling back:
|
||||
|
||||
- Do not present the fallback results as equivalent in precision to MCP tool results.
|
||||
|
||||
## Critical Constraints
|
||||
|
||||
- **NO GREP BY DEFAULT**: Never use `grep`, `ripgrep`, or `grep_search` to find Nim symbols or references unless the MCP tools have explicitly errored out.
|
||||
- **PROMPT ON EMPTY**: If MCP tools return nothing, you MUST ask the user before falling back to grep.
|
||||
- **NO MANUAL PARSING**: Do not read large Nim files just to extract symbol locations; use `nimListSymbols` instead.
|
||||
- **NO DIY FILE CHECKS**: Do not substitute manual inspection, ad-hoc compiler invocations, or `nimCheckProject` when `nimCheckFile` can return structured diagnostics for the specific file the user asked about.
|
||||
- **NO DIY PROJECT CHECKS**: Do not substitute shelling out to ad-hoc Nim commands, parsing compiler output, or manually inspecting many files when `nimCheckProject` can return structured project diagnostics.
|
||||
- **TOKEN CONSERVATION**: Minimize turns and context by using the most precise tool available.
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
- Calling `nimFindSymbols("Foo")` and then running `rg "Foo"` anyway.
|
||||
- Using `rg` for "find all usages" when `nimFindReferences` is available.
|
||||
- Reading multiple Nim files to manually enumerate definitions that `nimListSymbols` can return directly.
|
||||
- Reading a Nim file to manually search for a type definition when `nimFindTypeDefinition` can resolve it precisely from the symbol's cursor position.
|
||||
- Grepping for `type Foo* =` to find where a type is defined instead of using `nimFindTypeDefinition` or `nimFindSymbols`.
|
||||
- Manually scanning imports and cross-referencing to determine which module a symbol comes from, when `nimFindTypeDefinition` can give the exact module path.
|
||||
- Running `nimCheckProject()` when the user asked to check one specific Nim file and `nimCheckFile` is available.
|
||||
- Manually reading or building a single Nim file first when `nimCheckFile` can return structured diagnostics for it.
|
||||
- Running a manual project build or grep-based log scan first when the user asked for project/workspace/repository/package diagnostics and `nimCheckProject` is available.
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -52,3 +52,5 @@ tests/cbindings/data-dir
|
||||
tests/cbindings/downloaded_hello.txt
|
||||
|
||||
nimbledeps
|
||||
CLAUDE.local.md
|
||||
.claude/settings.local.json
|
||||
|
||||
9
.mcp.json
Normal file
9
.mcp.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"nim": {
|
||||
"type": "stdio",
|
||||
"command": "nimlangserver",
|
||||
"args": ["--mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
82
CLAUDE.md
Normal file
82
CLAUDE.md
Normal file
@ -0,0 +1,82 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# First-time setup (initializes nimbus-build-system submodule)
|
||||
make update && make
|
||||
|
||||
# Parallel build (faster)
|
||||
make -j$(nproc) update && make -j$(nproc)
|
||||
|
||||
# Build the storage binary only
|
||||
make
|
||||
|
||||
# Build the C shared/static library
|
||||
make libstorage # dynamic (.so/.dylib/.dll)
|
||||
make STATIC=1 libstorage # static (.a)
|
||||
|
||||
# Format code with nph
|
||||
make build-nph # build nph formatter first
|
||||
make nph/<path> # format a specific file or folder
|
||||
make format # format all nim sources
|
||||
make install-nph-hook # install git pre-commit hook for auto-formatting
|
||||
```
|
||||
|
||||
## Test Commands
|
||||
|
||||
```bash
|
||||
# Run unit tests (tests/storage/)
|
||||
make test
|
||||
|
||||
# Run integration tests (spawns real node processes)
|
||||
make testIntegration
|
||||
|
||||
# Run all tests
|
||||
make testAll
|
||||
|
||||
# Run a single test file directly
|
||||
$(ENV_SCRIPT) nim c -r tests/storage/testblockexchange.nim
|
||||
|
||||
# Run C bindings test
|
||||
make testLibstorage
|
||||
|
||||
# Coverage report (requires lcov)
|
||||
make coverage && make show-coverage
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
**Core node** (`storage/node.nim`): `StorageNode` composes all subsystems — a libp2p `Switch`, `NetworkStore`, `BlockExcEngine`, `Discovery`, `ManifestProtocol`, and `Taskpool`.
|
||||
|
||||
**Storage layer** (`storage/stores/`):
|
||||
- `BlockStore` — abstract base type with virtual methods
|
||||
- `RepoStore` — persistent LevelDB-backed store
|
||||
- `CacheStore` — in-memory cache
|
||||
- `NetworkStore` — wraps a local store with block exchange to fetch from the network
|
||||
|
||||
**Block exchange** (`storage/blockexchange/`): BitSwap-inspired protocol with an engine, network layer, and peer tracking. Blocks are identified by CID (Content Identifier).
|
||||
|
||||
**Manifest & Merkle tree** (`storage/manifest/`, `storage/merkletree/`): Files are split into chunks, organized in a Merkle tree, and described by a `Manifest`. The manifest CID is the user-facing handle for a stored file.
|
||||
|
||||
**REST API** (`storage/rest/`): HTTP API surface. See `openapi.yaml` for the full spec.
|
||||
|
||||
**C library bindings** (`library/`): `libstorage.nim` exposes a C ABI via `storage_new / storage_start / storage_stop / storage_destroy`. All API calls are async and deliver results via a `StorageCallback`. Callbacks must be fast and non-blocking (they run on the worker thread).
|
||||
|
||||
**Integration tests** (`tests/integration/`): Tests that spawn actual node processes. `twonodessuite` / `multinodesuite` macros set up N nodes and `StorageClient` (HTTP client) for interacting with them.
|
||||
|
||||
**Unit tests** (`tests/storage/`): Auto-discovered by the `importTests` macro — any file named `test*.nim` in that directory is included automatically in `testStorage`.
|
||||
|
||||
**Distributed tests** (`https://github.com/logos-storage/logos-storage-nim-cs-dist-tests): Uses Kubernetes to deploy a cluster either locally on Docker Desktop or on Google Cloud Platoform (using .github/workflows/release.yml in the logos-storage-nim repo).
|
||||
|
||||
## Key Development Notes
|
||||
|
||||
- **Nim version**: pinned to `v2.2.10` (see `Makefile`). Override with `NIM_COMMIT=<version>`.
|
||||
- **Memory model**: ORC (`--mm:orc`) for Nim ≥ 2.0, refc for the C library build.
|
||||
- **Error handling**: uses `questionable/results` (`?!T`, `?T`) throughout — avoid bare exceptions. The codebase enforces `{.push raises: [].}` broadly.
|
||||
- **Logging**: uses `chronicles` with runtime filtering. Topics are set per-module via `logScope`. Build with `-d:chronicles_log_level=TRACE` to enable all log levels.
|
||||
- **Style**: `--styleCheck:error` is enabled — identifiers must match declaration casing exactly.
|
||||
- **Formatting**: `nph` is the mandatory formatter. Run `make nph/<file>` before committing, or install the pre-commit hook.
|
||||
- **Chronicles sinks**: configured in `config.nims` as `textlines[dynamic],json[dynamic],textlines[dynamic]`. Adjust runtime behavior with the `CHRONICLES_LOG_LEVEL` env var or `--log-level` CLI flag.
|
||||
Loading…
x
Reference in New Issue
Block a user