eminiar 0.0.0-stage → 0.5.1
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.
- package/.claude-plugin/marketplace.json +12 -0
- package/.claude-plugin/plugin.json +28 -0
- package/LICENSE +21 -0
- package/README.md +206 -2
- package/bin/_resolve.sh +51 -0
- package/bin/em-hook +15 -0
- package/bin/em-server +12 -0
- package/bin/eminiar +22 -0
- package/dist/cli.js +43061 -0
- package/dist/hook.js +29771 -0
- package/dist/server.js +57525 -0
- package/dist/ui/app.global.js +96 -0
- package/dist/ui/index.html +24 -0
- package/dist/ui/styles.css +1658 -0
- package/eminiar.config.schema.json +424 -0
- package/hooks/hooks.json +73 -0
- package/package.json +94 -4
- package/skills/em-docs/SKILL.md +25 -0
- package/skills/em-doctor/SKILL.md +9 -0
- package/skills/em-graph/SKILL.md +29 -0
- package/skills/em-history/SKILL.md +43 -0
- package/skills/em-index/SKILL.md +14 -0
- package/skills/em-onboard/SKILL.md +47 -0
- package/skills/em-purge/SKILL.md +13 -0
- package/skills/em-search/SKILL.md +16 -0
- package/skills/em-stats/SKILL.md +9 -0
- package/skills/eminiar/SKILL.md +87 -0
- package/vendor/grammars/go.wasm +0 -0
- package/vendor/grammars/javascript.wasm +0 -0
- package/vendor/grammars/python.wasm +0 -0
- package/vendor/grammars/tsx.wasm +0 -0
- package/vendor/grammars/typescript.wasm +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eminiar",
|
|
3
|
+
"owner": { "name": "Ryan Dick" },
|
|
4
|
+
"description": "Local-first context, memory and knowledge graph plugin for Claude Code.",
|
|
5
|
+
"plugins": [
|
|
6
|
+
{
|
|
7
|
+
"name": "eminiar",
|
|
8
|
+
"source": "./",
|
|
9
|
+
"description": "Local-first context, memory and knowledge graph for Claude Code."
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eminiar",
|
|
3
|
+
"displayName": "Eminiar",
|
|
4
|
+
"version": "0.5.1",
|
|
5
|
+
"description": "Local-first context, memory and knowledge graph for Claude Code: sandboxed execution, FTS5 + vector search, session continuity, code graph.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Ryan Dick"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"context",
|
|
12
|
+
"memory",
|
|
13
|
+
"search",
|
|
14
|
+
"sandbox",
|
|
15
|
+
"knowledge-graph"
|
|
16
|
+
],
|
|
17
|
+
"hooks": "./hooks/hooks.json",
|
|
18
|
+
"mcpServers": {
|
|
19
|
+
"eminiar": {
|
|
20
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/em-server",
|
|
21
|
+
"args": [],
|
|
22
|
+
"env": {
|
|
23
|
+
"EMINIAR_PLUGIN_ROOT": "${CLAUDE_PLUGIN_ROOT}",
|
|
24
|
+
"EMINIAR_PLUGIN_DATA": "${CLAUDE_PLUGIN_DATA}"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ryan Dick
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,3 +1,207 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# eminiar
|
|
4
|
+
|
|
5
|
+
**A memory, a code map and a clean context window for Claude Code — all on your machine.**
|
|
6
|
+
|
|
7
|
+
*Pronounced ee-MIN-ee-ar*
|
|
8
|
+
|
|
9
|
+
[](#license)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](https://docs.claude.com/en/docs/claude-code)
|
|
12
|
+
[](docs/how-it-works.md#privacy-and-data)
|
|
13
|
+
|
|
14
|
+
[Quick start](#quick-start) · [Features](#what-you-get) · [How it works](docs/how-it-works.md) · [Tools](docs/tools.md) · [Docs](docs/README.md)
|
|
15
|
+
|
|
16
|
+
<br/>
|
|
17
|
+
|
|
18
|
+
<picture>
|
|
19
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/images/dashboard-explore-dark.webp">
|
|
20
|
+
<img alt="The eminiar dashboard: source explorer with file impact, dependents and linked memories" src="docs/images/dashboard-explore-light.webp" width="900">
|
|
21
|
+
</picture>
|
|
22
|
+
|
|
23
|
+
<sub>The local dashboard: source, file impact and the memories linked to the file.</sub>
|
|
24
|
+
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## The problem
|
|
30
|
+
|
|
31
|
+
Claude Code is very capable, but three things slow it down on a real project:
|
|
32
|
+
|
|
33
|
+
1. **The context window fills with noise.** One `git log`, test run or API response can use
|
|
34
|
+
thousands of tokens. Claude needs only a few lines of it.
|
|
35
|
+
2. **Every session starts from zero.** Decisions, constraints and fixed bugs are lost after a
|
|
36
|
+
`/compact` or a new session. Claude asks again, or repeats a mistake.
|
|
37
|
+
3. **Claude reads code without a map.** It does not know which files are fragile, which files
|
|
38
|
+
import a function, or why a line changed.
|
|
39
|
+
|
|
40
|
+
## The solution
|
|
41
|
+
|
|
42
|
+
eminiar is a Claude Code plugin. It adds an MCP server with 22 `em_*` tools and a set of hooks.
|
|
43
|
+
Everything runs locally in one SQLite database per project.
|
|
44
|
+
|
|
45
|
+
| | Without eminiar | With eminiar |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| **Large output** | The full output goes into context | Output is indexed. Only the sections that match your `intent` come back |
|
|
48
|
+
| **Memory** | Lost at `/compact` or a new session | Markdown memories in your repo, given back to Claude when they are relevant |
|
|
49
|
+
| **Code structure** | `grep` and full-file reads | A knowledge graph of files, symbols, calls, routes and hotspots |
|
|
50
|
+
| **Git history** | Raw `git log` / `git blame` | Classified commits, with each fix traced back to the commit that caused it |
|
|
51
|
+
| **Library docs** | Web search on each question | A local, searchable index of the docs your project uses |
|
|
52
|
+
| **Getting knowledge** | Claude must remember to ask | Hooks push the relevant knowledge to Claude **automatically** |
|
|
53
|
+
|
|
54
|
+
## What you get
|
|
55
|
+
|
|
56
|
+
### 🧪 Sandboxed execution — keep raw output out of context
|
|
57
|
+
|
|
58
|
+
`em_execute`, `em_batch_execute` and `em_execute_file` run shell, JavaScript and TypeScript, plus
|
|
59
|
+
Python, Ruby, Go, PHP, Perl, R, Elixir, Rust and C# when they are installed. Output over 5 KB is
|
|
60
|
+
indexed. Claude gets back only the sections that match its `intent`. Snippets obey your Claude
|
|
61
|
+
Code `permissions.deny` rules.
|
|
62
|
+
|
|
63
|
+
### 🔎 Hybrid search — keyword and meaning together
|
|
64
|
+
|
|
65
|
+
SQLite FTS5 (porter + trigram, BM25, typo correction) is fused with local ONNX embeddings
|
|
66
|
+
(`bge-small` through `sqlite-vec`). Search covers command output, files, fetched pages,
|
|
67
|
+
documentation, memories, git messages and session history. It never waits for the model to
|
|
68
|
+
download.
|
|
69
|
+
|
|
70
|
+
### 🧠 Memory that comes back by itself
|
|
71
|
+
|
|
72
|
+
`em_remember` writes plain markdown files to `.eminiar/memories/`. You can read them, edit them
|
|
73
|
+
and commit them. Decisions have an ADR-style status (`proposed`, `accepted`, `superseded`). Hooks
|
|
74
|
+
attach matching memories to your prompts, to file reads and edits, to failed commands and to
|
|
75
|
+
subagent briefs. **Claude does not have to remember to look.**
|
|
76
|
+
|
|
77
|
+
### 🕸️ Code knowledge graph — a map before an edit
|
|
78
|
+
|
|
79
|
+
tree-sitter parses TypeScript, JavaScript, Python and Go into files, symbols, imports, calls,
|
|
80
|
+
references, inheritance and HTTP routes (Express, Fastify, Koa, hapi, Hono, Moleculer, Next.js,
|
|
81
|
+
Python decorator routes and Go routers). eminiar
|
|
82
|
+
adds fan-in, complexity, churn, a hotspot score, module clusters, import cycles and git co-change
|
|
83
|
+
coupling. Ask *"what breaks if I change this?"* with `em_graph_impact`.
|
|
84
|
+
|
|
85
|
+
### 📜 Git history, read for Claude
|
|
86
|
+
|
|
87
|
+
`em_history` classifies every commit (feat, fix, refactor, perf …). It traces each fix back to
|
|
88
|
+
the commit that wrote the broken lines. Files get a risk score with reasons. Before Claude edits
|
|
89
|
+
a bug-prone file, it sees the record.
|
|
90
|
+
|
|
91
|
+
### 📚 Documentation knowledge base
|
|
92
|
+
|
|
93
|
+
`em_docs` finds your local docs (READMEs, ADRs, OpenAPI, Postman) and the libraries, services
|
|
94
|
+
and third-party APIs your code calls. It indexes their documentation locally. OpenAPI specs are
|
|
95
|
+
split into one section per endpoint, so a lookup returns the exact operation.
|
|
96
|
+
|
|
97
|
+
### 📊 Local dashboard
|
|
98
|
+
|
|
99
|
+
`eminiar ui` opens a local web app with token savings, a source explorer with impact analysis, a
|
|
100
|
+
graph "galaxy", an architecture map, a history explorer, a memory editor and a docs manager.
|
|
101
|
+
|
|
102
|
+
| | |
|
|
103
|
+
|:---:|:---:|
|
|
104
|
+
| [<img alt="Galaxy: the knowledge graph around a file" src="docs/images/dashboard-galaxy-dark.webp" width="430">](docs/dashboard.md#galaxy) | [<img alt="History: commits classified by kind, with the branch graph" src="docs/images/dashboard-history-dark.webp" width="430">](docs/dashboard.md#history) |
|
|
105
|
+
| **Galaxy:** the knowledge graph | **History:** classified commits and fix tracing |
|
|
106
|
+
| [<img alt="Memory: a decision with its linked files" src="docs/images/dashboard-memory-dark.webp" width="430">](docs/dashboard.md#memory) | [<img alt="Hotspots: fan-in, churn and complexity per file" src="docs/images/dashboard-hotspots-dark.webp" width="430">](docs/dashboard.md#architecture) |
|
|
107
|
+
| **Memory:** decisions linked to code | **Hotspots:** where change is risky |
|
|
108
|
+
|
|
109
|
+
## What Claude sees
|
|
110
|
+
|
|
111
|
+
Hooks add short notes to the conversation at the right moment. These examples are real output:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
eminiar recall — project memories and indexed docs that match this request:
|
|
115
|
+
- memory decision/proactive-recall-in-hooks [decision]: Project knowledge is pushed to Claude by hooks …
|
|
116
|
+
|
|
117
|
+
eminiar history: src/cli.ts is bug-prone (1/6 commits were fixes; 1 earlier change later needed
|
|
118
|
+
fixing; last fix 3f8c697 Fix MCP registration, make enforce routing and dev upgrades safe).
|
|
119
|
+
|
|
120
|
+
eminiar graph: src/cli.ts is imported by 6 files; em_graph_impact {node:"file:src/cli.ts"} lists
|
|
121
|
+
them before you change an exported signature.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Each note appears once per context window. After a `/compact`, notes come back when they are
|
|
125
|
+
relevant again.
|
|
126
|
+
|
|
127
|
+
## Quick start
|
|
128
|
+
|
|
129
|
+
**Requirements:** Node.js 22.12 or later, and Claude Code.
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
npx eminiar install # registers the plugin, installs a stable copy, downloads the model
|
|
133
|
+
npx eminiar doctor # checks every part
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Restart Claude Code. Then, in your project:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
/em-onboard # writes onboarding memories and builds the docs knowledge base
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
That is all. Use Claude Code as usual. To see how much context eminiar saves, run `/em-stats` or
|
|
143
|
+
open the dashboard with `eminiar ui`.
|
|
144
|
+
|
|
145
|
+
**For a team:** run `npx eminiar install --team` once and commit `eminiar.config.json` and
|
|
146
|
+
`.eminiar/`. Teammates then run `npx eminiar install`. See
|
|
147
|
+
[Getting started](docs/getting-started.md#team-setup).
|
|
148
|
+
|
|
149
|
+
## How it works
|
|
150
|
+
|
|
151
|
+
```mermaid
|
|
152
|
+
flowchart LR
|
|
153
|
+
CC["Claude Code"]
|
|
154
|
+
subgraph eminiar ["eminiar (local)"]
|
|
155
|
+
H["Hooks<br/>recall · routing · capture"]
|
|
156
|
+
S["MCP server<br/>22 em_* tools"]
|
|
157
|
+
SB["Sandbox<br/>shell · JS · TS · Python …"]
|
|
158
|
+
DB[("SQLite per project<br/>FTS5 · vectors · graph")]
|
|
159
|
+
M["Memory files<br/>.eminiar/memories/*.md"]
|
|
160
|
+
end
|
|
161
|
+
CC -->|prompts, tool calls| H
|
|
162
|
+
H -->|notes: memories, history, graph| CC
|
|
163
|
+
CC -->|em_* calls| S
|
|
164
|
+
S -->|small, relevant answers| CC
|
|
165
|
+
S --> SB
|
|
166
|
+
S <--> DB
|
|
167
|
+
H <--> DB
|
|
168
|
+
M <--> DB
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- **Hooks** run on session start, prompts, tool calls and failures. They capture session events,
|
|
172
|
+
route noisy commands to the sandbox, and attach relevant knowledge.
|
|
173
|
+
- **The MCP server** provides the `em_*` tools and keeps the index and graph up to date.
|
|
174
|
+
- **Storage** is one SQLite file per project under `~/.eminiar/`. Memories also live as markdown
|
|
175
|
+
in your repo.
|
|
176
|
+
|
|
177
|
+
Read more in [How it works](docs/how-it-works.md).
|
|
178
|
+
|
|
179
|
+
## Documentation
|
|
180
|
+
|
|
181
|
+
| Guide | Contents |
|
|
182
|
+
|---|---|
|
|
183
|
+
| [Getting started](docs/getting-started.md) | Install, team setup, first steps, upgrade and uninstall |
|
|
184
|
+
| [How it works](docs/how-it-works.md) | Architecture, routing modes, session continuity, privacy |
|
|
185
|
+
| [Tools reference](docs/tools.md) | Every `em_*` tool and slash command |
|
|
186
|
+
| [Memory and recall](docs/memory-and-recall.md) | Memory files, decisions, automatic recall |
|
|
187
|
+
| [Knowledge graph and history](docs/knowledge-graph.md) | Graph, symbols, impact analysis, git history |
|
|
188
|
+
| [Documentation knowledge base](docs/documentation-kb.md) | Discover, index and look up docs |
|
|
189
|
+
| [Dashboard](docs/dashboard.md) | The `eminiar ui` web app |
|
|
190
|
+
| [Configuration](docs/configuration.md) | Every config key with its default |
|
|
191
|
+
| [CLI](docs/cli.md) | The `eminiar` command |
|
|
192
|
+
| [Troubleshooting](docs/troubleshooting.md) | Common problems and fixes |
|
|
193
|
+
| [Development](docs/development.md) | Build, test, benchmark and project layout |
|
|
194
|
+
|
|
195
|
+
## Privacy
|
|
196
|
+
|
|
197
|
+
Your code, tool output and memories stay on your machine. eminiar uses the network only to:
|
|
198
|
+
|
|
199
|
+
- download the embedding model once (you can skip this with `install --no-model`);
|
|
200
|
+
- fetch web pages and documentation that you or Claude ask it to index;
|
|
201
|
+
- look up package metadata in the npm, PyPI and Go registries when it adds documentation.
|
|
202
|
+
|
|
203
|
+
The dashboard listens on `127.0.0.1` only.
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT © Ryan Dick
|
package/bin/_resolve.sh
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Sourced by bin/em-server, bin/em-hook and bin/eminiar (never executed directly).
|
|
3
|
+
# Sets NODE (the Node binary to run) and RUN (the package root whose dist/ to run).
|
|
4
|
+
#
|
|
5
|
+
# Claude Code may launch a plugin from the copy it keeps under
|
|
6
|
+
# ~/.claude/plugins/cache/<marketplace>/<plugin>/<version>. That copy carries dist/
|
|
7
|
+
# but no node_modules/, so dist/*.js cannot import better-sqlite3 and friends. The
|
|
8
|
+
# installer pins the stable copy (~/.eminiar/plugin/node_modules/eminiar, with its
|
|
9
|
+
# dependencies beside it) in $EMINIAR_HOME/root-path; when the directory this shim
|
|
10
|
+
# lives in cannot resolve its dependencies, we run the pinned copy's dist/ instead.
|
|
11
|
+
EM_HOME="${EMINIAR_HOME:-$HOME/.eminiar}"
|
|
12
|
+
# EM_SELF: the shim's real path when it was reached through a symlink (bin/eminiar).
|
|
13
|
+
DIR="$(cd "$(dirname "${EM_SELF:-$0}")/.." && pwd)"
|
|
14
|
+
|
|
15
|
+
# V8 compile cache (Node >= 22.1): bytecode for dist/*.js is reused across launches,
|
|
16
|
+
# trimming server and hook start-up. Older Node ignores the variable.
|
|
17
|
+
if [ -z "$NODE_COMPILE_CACHE" ]; then
|
|
18
|
+
NODE_COMPILE_CACHE="$EM_HOME/compile-cache"
|
|
19
|
+
export NODE_COMPILE_CACHE
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Node: the binary pinned at install time (so nvm/volta PATHs never matter), else PATH.
|
|
23
|
+
NODE=""
|
|
24
|
+
if [ -f "$EM_HOME/node-path" ]; then
|
|
25
|
+
NODE="$(cat "$EM_HOME/node-path" 2>/dev/null)"
|
|
26
|
+
fi
|
|
27
|
+
if [ ! -x "$NODE" ]; then
|
|
28
|
+
NODE="$(command -v node 2>/dev/null)"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# A package root is runnable when its dependencies resolve: node_modules/ inside it
|
|
32
|
+
# (dev checkout, npm -g) or beside it (stable copy inside ~/.eminiar/plugin/node_modules).
|
|
33
|
+
em_runnable() {
|
|
34
|
+
[ -e "$1/node_modules/better-sqlite3/package.json" ] || [ -e "$1/../better-sqlite3/package.json" ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
RUN="$DIR"
|
|
38
|
+
if ! em_runnable "$DIR"; then
|
|
39
|
+
RUN=""
|
|
40
|
+
if [ -f "$EM_HOME/root-path" ]; then
|
|
41
|
+
ALT="$(cat "$EM_HOME/root-path" 2>/dev/null)"
|
|
42
|
+
if [ -n "$ALT" ] && [ -f "$ALT/dist/server.js" ] && em_runnable "$ALT"; then
|
|
43
|
+
RUN="$ALT"
|
|
44
|
+
# Point version/grammar lookups at the code that actually runs; keep the
|
|
45
|
+
# launch directory for diagnostics (em_doctor shows "launched from").
|
|
46
|
+
EMINIAR_PLUGIN_ROOT="$ALT"
|
|
47
|
+
EMINIAR_LAUNCH_ROOT="$DIR"
|
|
48
|
+
export EMINIAR_PLUGIN_ROOT EMINIAR_LAUNCH_ROOT
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
fi
|
package/bin/em-hook
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Hook entry shim. Node and package-root resolution live in _resolve.sh.
|
|
3
|
+
# A hook must never block Claude: if nothing can run, print an empty JSON object.
|
|
4
|
+
. "$(dirname "$0")/_resolve.sh"
|
|
5
|
+
if [ ! -x "$NODE" ]; then
|
|
6
|
+
echo "eminiar hook: no node binary found (run: npx eminiar install)" >&2
|
|
7
|
+
echo '{}'
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
if [ -z "$RUN" ]; then
|
|
11
|
+
echo "eminiar hook: $DIR has no node_modules and no stable copy is pinned (run: npx eminiar install)" >&2
|
|
12
|
+
echo '{}'
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
exec "$NODE" "$RUN/dist/hook.js" "$@"
|
package/bin/em-server
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# MCP server shim (stdio). Node and package-root resolution live in _resolve.sh.
|
|
3
|
+
. "$(dirname "$0")/_resolve.sh"
|
|
4
|
+
if [ ! -x "$NODE" ]; then
|
|
5
|
+
echo "eminiar: no node binary found (run: npx eminiar install)" >&2
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
if [ -z "$RUN" ]; then
|
|
9
|
+
echo "eminiar: $DIR has no node_modules and no stable copy is pinned in $EM_HOME/root-path (run: npx eminiar install)" >&2
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
exec "$NODE" "$RUN/dist/server.js" "$@"
|
package/bin/eminiar
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# CLI shim. Node and package-root resolution live in _resolve.sh.
|
|
3
|
+
# npm links this file into node_modules/.bin (npx, npm -g) as a symlink; follow it so
|
|
4
|
+
# _resolve.sh and the package root are found next to the real file.
|
|
5
|
+
EM_SELF="$0"
|
|
6
|
+
while [ -L "$EM_SELF" ]; do
|
|
7
|
+
EM_LINK="$(readlink "$EM_SELF")"
|
|
8
|
+
case "$EM_LINK" in
|
|
9
|
+
/*) EM_SELF="$EM_LINK" ;;
|
|
10
|
+
*) EM_SELF="$(dirname "$EM_SELF")/$EM_LINK" ;;
|
|
11
|
+
esac
|
|
12
|
+
done
|
|
13
|
+
. "$(dirname "$EM_SELF")/_resolve.sh"
|
|
14
|
+
if [ ! -x "$NODE" ]; then
|
|
15
|
+
echo "eminiar: node >= 22.12 is required" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
if [ -z "$RUN" ]; then
|
|
19
|
+
echo "eminiar: $DIR has no node_modules and no stable copy is pinned in $EM_HOME/root-path (run: npx eminiar install)" >&2
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
exec "$NODE" "$RUN/dist/cli.js" "$@"
|