Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
760 changes: 651 additions & 109 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Contributions are welcome. This guide covers setup, testing, and PR guidelines.
**Prerequisites**: C compiler (gcc or clang), make, zlib, Git. Optional: Node.js 22+ (for graph UI).

```bash
git clone https://github.com/DeusData/codebase-memory-mcp.git
git clone https://github.com/hodizoda/codebase-memory-mcp.git
cd codebase-memory-mcp
git config core.hooksPath scripts/hooks # activates pre-commit security checks
scripts/build.sh
Expand Down Expand Up @@ -160,7 +160,7 @@ If you add a new `system()`, `popen()`, `fork()`, or network call, it must be ju

## Good First Issues

Check [issues labeled `good first issue`](https://github.com/DeusData/codebase-memory-mcp/labels/good%20first%20issue) for beginner-friendly tasks with clear scope and guidance.
Check [issues labeled `good first issue`](https://github.com/hodizoda/codebase-memory-mcp/labels/good%20first%20issue) for beginner-friendly tasks with clear scope and guidance.

## License

Expand Down
73 changes: 70 additions & 3 deletions Makefile.cbm
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,25 @@ PIPELINE_SRCS = \
src/pipeline/pass_semantic_edges.c \
src/pipeline/pass_cross_repo.c \
src/pipeline/artifact.c \
src/pipeline/pass_pkgmap.c
src/pipeline/pass_pkgmap.c \
src/pipeline/pass_servicelinks.c \
src/pipeline/servicelink_graphql.c \
src/pipeline/servicelink_grpc.c \
src/pipeline/servicelink_kafka.c \
src/pipeline/servicelink_sqs.c \
src/pipeline/servicelink_sns.c \
src/pipeline/servicelink_ws.c \
src/pipeline/servicelink_sse.c \
src/pipeline/servicelink_pubsub.c \
src/pipeline/servicelink_rabbitmq.c \
src/pipeline/servicelink_eventbridge.c \
src/pipeline/servicelink_mqtt.c \
src/pipeline/servicelink_nats.c \
src/pipeline/servicelink_redis_pubsub.c \
src/pipeline/servicelink_trpc.c \
src/pipeline/servicelink_http.c \
src/pipeline/pass_communities.c \
src/pipeline/pass_crossrepolinks.c

# SimHash / MinHash module
SIMHASH_SRCS = src/simhash/minhash.c
Expand Down Expand Up @@ -314,6 +332,36 @@ TEST_INTEGRATION_SRCS = tests/test_integration.c tests/test_incremental.c
TEST_TRACES_SRCS = tests/test_traces.c


TEST_SERVICELINK_GRAPHQL_SRCS = tests/test_servicelink_graphql.c

TEST_SERVICELINK_GRPC_SRCS = tests/test_servicelink_grpc.c

TEST_SERVICELINK_KAFKA_SRCS = tests/test_servicelink_kafka.c

TEST_SERVICELINK_SQS_SRCS = tests/test_servicelink_sqs.c

TEST_SERVICELINK_SNS_SRCS = tests/test_servicelink_sns.c

TEST_SERVICELINK_WS_SRCS = tests/test_servicelink_ws.c

TEST_SERVICELINK_SSE_SRCS = tests/test_servicelink_sse.c

TEST_SERVICELINK_PUBSUB_SRCS = tests/test_servicelink_pubsub.c

TEST_SERVICELINK_RABBITMQ_SRCS = tests/test_servicelink_rabbitmq.c

TEST_SERVICELINK_EVENTBRIDGE_SRCS = tests/test_servicelink_eventbridge.c

TEST_SERVICELINK_MQTT_SRCS = tests/test_servicelink_mqtt.c

TEST_SERVICELINK_NATS_SRCS = tests/test_servicelink_nats.c

TEST_SERVICELINK_REDIS_PUBSUB_SRCS = tests/test_servicelink_redis_pubsub.c

TEST_SERVICELINK_TRPC_SRCS = tests/test_servicelink_trpc.c

TEST_SERVICELINK_HTTP_SRCS = tests/test_servicelink_http.c

TEST_CLI_SRCS = tests/test_cli.c

TEST_MEM_SRCS = tests/test_mem.c
Expand All @@ -326,8 +374,27 @@ TEST_YAML_SRCS = tests/test_yaml.c

TEST_SIMHASH_SRCS = tests/test_simhash.c

ALL_TEST_SRCS = $(TEST_FOUNDATION_SRCS) $(TEST_EXTRACTION_SRCS) $(TEST_STORE_SRCS) $(TEST_CYPHER_SRCS) $(TEST_MCP_SRCS) $(TEST_DISCOVER_SRCS) $(TEST_GRAPH_BUFFER_SRCS) $(TEST_PIPELINE_SRCS) $(TEST_WATCHER_SRCS) $(TEST_LZ4_SRCS) $(TEST_ZSTD_SRCS) $(TEST_ARTIFACT_SRCS) $(TEST_SQLITE_WRITER_SRCS) $(TEST_GO_LSP_SRCS) $(TEST_C_LSP_SRCS) $(TEST_TRACES_SRCS) $(TEST_CLI_SRCS) $(TEST_MEM_SRCS) $(TEST_UI_SRCS) $(TEST_SECURITY_SRCS) $(TEST_YAML_SRCS) $(TEST_SIMHASH_SRCS) $(TEST_INTEGRATION_SRCS)

TEST_SERVICELINK_GRAPHQL_SRCS = tests/test_servicelink_graphql.c
TEST_SERVICELINK_GRPC_SRCS = tests/test_servicelink_grpc.c
TEST_SERVICELINK_KAFKA_SRCS = tests/test_servicelink_kafka.c
TEST_SERVICELINK_SQS_SRCS = tests/test_servicelink_sqs.c
TEST_SERVICELINK_SNS_SRCS = tests/test_servicelink_sns.c
TEST_SERVICELINK_WS_SRCS = tests/test_servicelink_ws.c
TEST_SERVICELINK_SSE_SRCS = tests/test_servicelink_sse.c
TEST_SERVICELINK_PUBSUB_SRCS = tests/test_servicelink_pubsub.c
TEST_SERVICELINK_RABBITMQ_SRCS = tests/test_servicelink_rabbitmq.c
TEST_SERVICELINK_EVENTBRIDGE_SRCS = tests/test_servicelink_eventbridge.c
TEST_SERVICELINK_MQTT_SRCS = tests/test_servicelink_mqtt.c
TEST_SERVICELINK_NATS_SRCS = tests/test_servicelink_nats.c
TEST_SERVICELINK_REDIS_PUBSUB_SRCS = tests/test_servicelink_redis_pubsub.c
TEST_SERVICELINK_TRPC_SRCS = tests/test_servicelink_trpc.c
TEST_SERVICELINK_HTTP_SRCS = tests/test_servicelink_http.c
TEST_COMMUNITIES_SRCS = tests/test_communities.c
TEST_ENDPOINT_REGISTRY_SRCS = tests/test_endpoint_registry.c
TEST_ENDPOINT_PERSISTENCE_SRCS = tests/test_endpoint_persistence.c
TEST_CROSS_PROJECT_LINKS_SRCS = tests/test_cross_project_links.c

ALL_TEST_SRCS = $(TEST_FOUNDATION_SRCS) $(TEST_EXTRACTION_SRCS) $(TEST_STORE_SRCS) $(TEST_CYPHER_SRCS) $(TEST_MCP_SRCS) $(TEST_DISCOVER_SRCS) $(TEST_GRAPH_BUFFER_SRCS) $(TEST_PIPELINE_SRCS) $(TEST_WATCHER_SRCS) $(TEST_LZ4_SRCS) $(TEST_ZSTD_SRCS) $(TEST_ARTIFACT_SRCS) $(TEST_SQLITE_WRITER_SRCS) $(TEST_GO_LSP_SRCS) $(TEST_C_LSP_SRCS) $(TEST_TRACES_SRCS) $(TEST_CLI_SRCS) $(TEST_MEM_SRCS) $(TEST_UI_SRCS) $(TEST_SECURITY_SRCS) $(TEST_YAML_SRCS) $(TEST_SIMHASH_SRCS) $(TEST_INTEGRATION_SRCS) $(TEST_SERVICELINK_GRAPHQL_SRCS) $(TEST_SERVICELINK_GRPC_SRCS) $(TEST_SERVICELINK_KAFKA_SRCS) $(TEST_SERVICELINK_SQS_SRCS) $(TEST_SERVICELINK_SNS_SRCS) $(TEST_SERVICELINK_WS_SRCS) $(TEST_SERVICELINK_SSE_SRCS) $(TEST_SERVICELINK_PUBSUB_SRCS) $(TEST_SERVICELINK_RABBITMQ_SRCS) $(TEST_SERVICELINK_EVENTBRIDGE_SRCS) $(TEST_SERVICELINK_MQTT_SRCS) $(TEST_SERVICELINK_NATS_SRCS) $(TEST_SERVICELINK_REDIS_PUBSUB_SRCS) $(TEST_SERVICELINK_TRPC_SRCS) $(TEST_SERVICELINK_HTTP_SRCS) $(TEST_COMMUNITIES_SRCS) $(TEST_ENDPOINT_REGISTRY_SRCS) $(TEST_ENDPOINT_PERSISTENCE_SRCS) $(TEST_CROSS_PROJECT_LINKS_SRCS)

# ── Build directories ────────────────────────────────────────────

Expand Down
73 changes: 16 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# codebase-memory-mcp

[![GitHub Release](https://img.shields.io/github/v/release/DeusData/codebase-memory-mcp?style=flat&color=blue)](https://github.com/DeusData/codebase-memory-mcp/releases/latest)
[![GitHub Release](https://img.shields.io/github/v/release/hodizoda/codebase-memory-mcp?style=flat&color=blue)](https://github.com/hodizoda/codebase-memory-mcp/releases/latest)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![CI](https://img.shields.io/github/actions/workflow/status/DeusData/codebase-memory-mcp/dry-run.yml?label=CI)](https://github.com/DeusData/codebase-memory-mcp/actions/workflows/dry-run.yml)
[![Tests](https://img.shields.io/badge/tests-2586_passing-brightgreen)](https://github.com/DeusData/codebase-memory-mcp)
Expand All @@ -15,7 +15,7 @@

**The fastest and most efficient code intelligence engine for AI coding agents.** Full-indexes an average repository in milliseconds, the Linux kernel (28M LOC, 75K files) in 3 minutes. Answers structural queries in under 1ms. Ships as a single static binary for macOS, Linux, and Windows — download, run `install`, done.

High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-sitter/) AST analysis across all 66 languages, enhanced with LSP-style hybrid type resolution for Go, C, and C++ (more languages coming soon) — producing a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. 14 MCP tools. Zero dependencies. Plug and play across 10 coding agents.
High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-sitter/) AST analysis across all 64 languages, enhanced with LSP-style hybrid type resolution for Go, C, and C++ (more languages coming soon) — producing a persistent knowledge graph of functions, classes, call chains, HTTP routes, and cross-service links. 14 MCP tools. Zero dependencies. Plug and play across 10 coding agents.

> **Research** — The design and benchmarks behind this project are described in the preprint [*Codebase-Memory: Tree-Sitter-Based Knowledge Graphs for LLM Code Exploration via MCP*](https://arxiv.org/abs/2603.27277) (arXiv:2603.27277). Evaluated across 31 real-world repositories: 83% answer quality, 10× fewer tokens, 2.1× fewer tool calls vs. file-by-file exploration.

Expand All @@ -31,19 +31,17 @@ High-quality parsing through [tree-sitter](https://tree-sitter.github.io/tree-si

- **Extreme indexing speed** — Linux kernel (28M LOC, 75K files) in 3 minutes. RAM-first pipeline: LZ4 compression, in-memory SQLite, fused Aho-Corasick pattern matching. Memory released after indexing.
- **Plug and play** — single static binary for macOS (arm64/amd64), Linux (arm64/amd64), and Windows (amd64). No Docker, no runtime dependencies, no API keys. Download → `install` → restart agent → done.
- **66 languages** — vendored tree-sitter grammars compiled into the binary. Nothing to install, nothing that breaks.
- **64 languages** — vendored tree-sitter grammars compiled into the binary. Nothing to install, nothing that breaks.
- **120x fewer tokens** — 5 structural queries: ~3,400 tokens vs ~412,000 via file-by-file search. One graph query replaces dozens of grep/read cycles.
- **11 agents, one command** — `install` auto-detects Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider, KiloCode, VS Code, OpenClaw, and Kiro — configures MCP entries, instruction files, and pre-tool hooks for each.
- **Built-in graph visualization** — 3D interactive UI at `localhost:9749` (optional UI binary variant).
- **Infrastructure-as-code indexing** — Dockerfiles, Kubernetes manifests, and Kustomize overlays indexed as graph nodes with cross-references. `Resource` nodes for K8s kinds, `Module` nodes for Kustomize overlays with `IMPORTS` edges to referenced resources.
- **14 MCP tools** — search, trace, architecture, impact analysis, Cypher queries, dead code detection, cross-service HTTP linking, ADR management, and more.

## Quick Start

**One-line install** (macOS / Linux):
```bash
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
```
1. **Download** the binary for your platform from the [latest release](https://github.com/hodizoda/codebase-memory-mcp/releases/latest):
- `codebase-memory-mcp-<os>-<arch>.tar.gz` — standard (MCP server only)
- `codebase-memory-mcp-ui-<os>-<arch>.tar.gz` — with embedded graph visualization

With graph visualization UI:
```bash
Expand Down Expand Up @@ -79,19 +77,11 @@ Restart your coding agent. Say **"Index this project"** — done.
macOS / Linux:
```bash
tar xzf codebase-memory-mcp-*.tar.gz
./install.sh
mv codebase-memory-mcp ~/.local/bin/
codebase-memory-mcp install
```

Windows (PowerShell):
```powershell
Expand-Archive codebase-memory-mcp-windows-amd64.zip -DestinationPath .
.\install.ps1
```

3. **Restart** your coding agent.

The `install` command automatically strips macOS quarantine attributes and ad-hoc signs the binary — no manual `xattr`/`codesign` needed.
</details>
3. **Restart** your coding agent. Say **"Index this project"** — done.

The `install` command auto-detects all installed coding agents and configures MCP server entries, instruction files, skills, and pre-tool hooks for each.

Expand Down Expand Up @@ -204,21 +194,21 @@ Every release includes `checksums.txt` with SHA-256 hashes. All binaries are sta
**macOS / Linux:**

```bash
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/scripts/setup.sh | bash
curl -fsSL https://raw.githubusercontent.com/hodizoda/codebase-memory-mcp/main/scripts/setup.sh | bash
```

**Windows (PowerShell):**

```powershell
irm https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/scripts/setup-windows.ps1 | iex
irm https://raw.githubusercontent.com/hodizoda/codebase-memory-mcp/main/scripts/setup-windows.ps1 | iex
```

</details>

### Install via Claude Code

```
You: "Install this MCP server: https://github.com/DeusData/codebase-memory-mcp"
You: "Install this MCP server: https://github.com/hodizoda/codebase-memory-mcp"
```

### Build from Source
Expand All @@ -236,7 +226,7 @@ You: "Install this MCP server: https://github.com/DeusData/codebase-memory-mcp"
</details>

```bash
git clone https://github.com/DeusData/codebase-memory-mcp.git
git clone https://github.com/hodizoda/codebase-memory-mcp.git
cd codebase-memory-mcp
scripts/build.sh # standard binary
scripts/build.sh --with-ui # with graph visualization
Expand Down Expand Up @@ -328,7 +318,7 @@ codebase-memory-mcp cli --raw search_graph '{"label": "Function"}' | jq '.result

### Node Labels

`Project`, `Package`, `Folder`, `File`, `Module`, `Class`, `Function`, `Method`, `Interface`, `Enum`, `Type`, `Route`, `Resource`
`Project`, `Package`, `Folder`, `File`, `Module`, `Class`, `Function`, `Method`, `Interface`, `Enum`, `Type`, `Route`

### Edge Types

Expand All @@ -355,37 +345,6 @@ codebase-memory-mcp config set auto_index_limit 50000 # max files for auto-in
codebase-memory-mcp config reset auto_index # reset to default
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `CBM_CACHE_DIR` | `~/.cache/codebase-memory-mcp` | Override the database storage directory. All project indexes and config are stored here. |
| `CBM_DIAGNOSTICS` | `false` | Set to `1` or `true` to enable periodic diagnostics output to `/tmp/cbm-diagnostics-<pid>.json`. |
| `CBM_DOWNLOAD_URL` | *(GitHub releases)* | Override the download URL for updates. Used for testing or self-hosted deployments. |

```bash
# Store indexes in a custom directory
export CBM_CACHE_DIR=~/my-projects/cbm-data
```

## Custom File Extensions

Map additional file extensions to supported languages via JSON config files. Useful for framework-specific extensions like `.blade.php` (Laravel) or `.mjs` (ES modules).

**Per-project** (in your repo root):
```json
// .codebase-memory.json
{"extra_extensions": {".blade.php": "php", ".mjs": "javascript"}}
```

**Global** (applies to all projects):
```json
// ~/.config/codebase-memory-mcp/config.json (or $XDG_CONFIG_HOME/...)
{"extra_extensions": {".twig": "html", ".phtml": "php"}}
```

Project config overrides global for conflicting extensions. Unknown language values are silently skipped. Missing config files are ignored.

## Persistence

SQLite databases stored at `~/.cache/codebase-memory-mcp/`. Persists across restarts (WAL mode, ACID-safe). To reset: `rm -rf ~/.cache/codebase-memory-mcp/`.
Expand All @@ -403,7 +362,7 @@ SQLite databases stored at `~/.cache/codebase-memory-mcp/`. Persists across rest

## Language Support

66 languages. Benchmarked against 64 real open-source repositories (78 to 49K nodes):
64 languages. Benchmarked against 64 real open-source repositories (78 to 49K nodes):

| Tier | Score | Languages |
|------|-------|-----------|
Expand All @@ -428,7 +387,7 @@ src/
traces/ Runtime trace ingestion
ui/ Embedded HTTP server + 3D graph visualization
foundation/ Platform abstractions (threads, filesystem, logging, memory)
internal/cbm/ Vendored tree-sitter grammars (66 languages) + AST extraction engine
internal/cbm/ Vendored tree-sitter grammars (64 languages) + AST extraction engine
```

## Security
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Users can independently verify any release binary:

```bash
# SLSA provenance (proves binary came from this repo's CI)
gh attestation verify <downloaded-file> --repo DeusData/codebase-memory-mcp
gh attestation verify <downloaded-file> --repo hodizoda/codebase-memory-mcp

# Sigstore cosign (keyless signature)
cosign verify-blob --bundle <file>.bundle <file>
Expand Down
12 changes: 6 additions & 6 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ <h1>codebase-memory-mcp</h1>
</div>
</div>
<div class="cta-buttons">
<a href="https://github.com/DeusData/codebase-memory-mcp" class="cta-primary">View on GitHub</a>
<a href="https://github.com/DeusData/codebase-memory-mcp/releases/latest" class="cta-secondary">Download Latest Release</a>
<a href="https://github.com/hodizoda/codebase-memory-mcp" class="cta-primary">View on GitHub</a>
<a href="https://github.com/hodizoda/codebase-memory-mcp/releases/latest" class="cta-secondary">Download Latest Release</a>
</div>
</section>

Expand Down Expand Up @@ -338,7 +338,7 @@ <h2>Benchmark results</h2>
</table>
<p style="color: var(--text-secondary); font-size: 0.875rem; margin-top: 8px;">
Tested across 31 languages with agent-vs-agent methodology (372 questions).
<a href="https://github.com/DeusData/codebase-memory-mcp/blob/main/BENCHMARK_REPORT.md">Full benchmark report &rarr;</a>
<a href="https://github.com/hodizoda/codebase-memory-mcp/blob/main/BENCHMARK_REPORT.md">Full benchmark report &rarr;</a>
</p>
</section>

Expand Down Expand Up @@ -425,9 +425,9 @@ <h2>How it compares</h2>
<div class="container">
<p>
Open source, MIT licensed.
<a href="https://github.com/DeusData/codebase-memory-mcp">GitHub</a> &middot;
<a href="https://github.com/DeusData/codebase-memory-mcp/releases/latest">Releases</a> &middot;
<a href="https://github.com/DeusData/codebase-memory-mcp/blob/main/BENCHMARK_REPORT.md">Benchmarks</a>
<a href="https://github.com/hodizoda/codebase-memory-mcp">GitHub</a> &middot;
<a href="https://github.com/hodizoda/codebase-memory-mcp/releases/latest">Releases</a> &middot;
<a href="https://github.com/hodizoda/codebase-memory-mcp/blob/main/BENCHMARK_REPORT.md">Benchmarks</a>
</p>
</div>
</footer>
Expand Down
7 changes: 3 additions & 4 deletions scripts/security-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ src/foundation/compat_fs.c:fork:cbm_exec_no_shell — fork+execvp for shell-free
src/foundation/compat_fs.c:execvp:cbm_exec_no_shell — direct exec without shell interpretation

# ── CLI: update command (user-initiated, interactive) ──────────────────────
src/cli/cli.c:system:curl download of release binary (update cmd)
src/cli/cli.c:cbm_popen:sha256 checksum verification (update cmd)
src/cli/cli.c:cbm_popen:pgrep for kill_other_instances (hardcoded process name)
src/cli/cli.c:popen:sha256 checksum computation via shasum

# ── Watcher: git status polling (repo paths validated via cbm_validate_shell_arg) ──
Expand Down Expand Up @@ -45,7 +45,6 @@ src/ui/http_server.c:execl:exec indexing binary in child process

# ── Allowed URLs ───────────────────────────────────────────────────────────
# Format: URL:justification
URL:https://api.github.com/repos/DeusData/codebase-memory-mcp/releases/latest:update check
URL:https://github.com/DeusData/codebase-memory-mcp/releases/latest/download:binary download + checksums
URL:https://github.com/DeusData/codebase-memory-mcp/releases/latest:version check via redirect header
URL:https://api.github.com/repos/hodizoda/codebase-memory-mcp/releases/latest:update check
URL:https://github.com/hodizoda/codebase-memory-mcp/releases/latest/download/:binary download + checksums
URL:http://127.0.0.1:UI server binding (localhost only)
2 changes: 1 addition & 1 deletion scripts/security-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ if [[ -d "$SKILLS_DIR" ]]; then
done

# Check for unexpected URLs
if grep -oE 'https?://[^\s"'"'"']+' "$skill_file" 2>/dev/null | grep -v 'github.com/DeusData' | grep -v 'localhost' | grep -v '127.0.0.1' > /tmp/sec_skill_urls 2>/dev/null; then
if grep -oE 'https?://[^\s"'"'"']+' "$skill_file" 2>/dev/null | grep -v 'github.com/hodizoda' | grep -v 'localhost' | grep -v '127.0.0.1' > /tmp/sec_skill_urls 2>/dev/null; then
while IFS= read -r url; do
echo "REVIEW: Skill '$basename' contains URL: $url"
done < /tmp/sec_skill_urls
Expand Down
Loading