engrm 0.1.0 → 0.2.0
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/README.md +214 -73
- package/bin/build.mjs +97 -0
- package/bin/engrm.mjs +13 -0
- package/dist/cli.js +2712 -0
- package/dist/hooks/elicitation-result.js +1786 -0
- package/dist/hooks/post-tool-use.js +2357 -0
- package/dist/hooks/pre-compact.js +1321 -0
- package/dist/hooks/sentinel.js +1168 -0
- package/dist/hooks/session-start.js +1473 -0
- package/dist/hooks/stop.js +1834 -0
- package/dist/server.js +16628 -0
- package/package.json +29 -4
- package/packs/api-best-practices.json +182 -0
- package/packs/nextjs-patterns.json +68 -0
- package/packs/node-security.json +68 -0
- package/packs/python-django.json +68 -0
- package/packs/react-gotchas.json +182 -0
- package/packs/typescript-patterns.json +67 -0
- package/packs/web-security.json +182 -0
- package/.mcp.json +0 -9
- package/AUTH-DESIGN.md +0 -436
- package/BRIEF.md +0 -197
- package/CLAUDE.md +0 -44
- package/COMPETITIVE.md +0 -174
- package/CONTEXT-OPTIMIZATION.md +0 -305
- package/INFRASTRUCTURE.md +0 -252
- package/MARKET.md +0 -230
- package/PLAN.md +0 -278
- package/SENTINEL.md +0 -293
- package/SERVER-API-PLAN.md +0 -553
- package/SPEC.md +0 -843
- package/SWOT.md +0 -148
- package/SYNC-ARCHITECTURE.md +0 -294
- package/VIBE-CODER-STRATEGY.md +0 -250
- package/bun.lock +0 -375
- package/hooks/post-tool-use.ts +0 -144
- package/hooks/session-start.ts +0 -64
- package/hooks/stop.ts +0 -131
- package/mem-page.html +0 -1305
- package/src/capture/dedup.test.ts +0 -103
- package/src/capture/dedup.ts +0 -76
- package/src/capture/extractor.test.ts +0 -245
- package/src/capture/extractor.ts +0 -330
- package/src/capture/quality.test.ts +0 -168
- package/src/capture/quality.ts +0 -104
- package/src/capture/retrospective.test.ts +0 -115
- package/src/capture/retrospective.ts +0 -121
- package/src/capture/scanner.test.ts +0 -131
- package/src/capture/scanner.ts +0 -100
- package/src/capture/scrubber.test.ts +0 -144
- package/src/capture/scrubber.ts +0 -181
- package/src/cli.ts +0 -517
- package/src/config.ts +0 -238
- package/src/context/inject.test.ts +0 -940
- package/src/context/inject.ts +0 -382
- package/src/embeddings/backfill.ts +0 -50
- package/src/embeddings/embedder.test.ts +0 -76
- package/src/embeddings/embedder.ts +0 -139
- package/src/lifecycle/aging.test.ts +0 -103
- package/src/lifecycle/aging.ts +0 -36
- package/src/lifecycle/compaction.test.ts +0 -264
- package/src/lifecycle/compaction.ts +0 -190
- package/src/lifecycle/purge.test.ts +0 -100
- package/src/lifecycle/purge.ts +0 -37
- package/src/lifecycle/scheduler.test.ts +0 -120
- package/src/lifecycle/scheduler.ts +0 -101
- package/src/provisioning/browser-auth.ts +0 -172
- package/src/provisioning/provision.test.ts +0 -198
- package/src/provisioning/provision.ts +0 -94
- package/src/register.test.ts +0 -167
- package/src/register.ts +0 -178
- package/src/server.ts +0 -436
- package/src/storage/migrations.test.ts +0 -244
- package/src/storage/migrations.ts +0 -261
- package/src/storage/outbox.test.ts +0 -229
- package/src/storage/outbox.ts +0 -131
- package/src/storage/projects.test.ts +0 -137
- package/src/storage/projects.ts +0 -184
- package/src/storage/sqlite.test.ts +0 -798
- package/src/storage/sqlite.ts +0 -934
- package/src/storage/vec.test.ts +0 -198
- package/src/sync/auth.test.ts +0 -76
- package/src/sync/auth.ts +0 -68
- package/src/sync/client.ts +0 -183
- package/src/sync/engine.test.ts +0 -94
- package/src/sync/engine.ts +0 -127
- package/src/sync/pull.test.ts +0 -279
- package/src/sync/pull.ts +0 -170
- package/src/sync/push.test.ts +0 -117
- package/src/sync/push.ts +0 -230
- package/src/tools/get.ts +0 -34
- package/src/tools/pin.ts +0 -47
- package/src/tools/save.test.ts +0 -301
- package/src/tools/save.ts +0 -231
- package/src/tools/search.test.ts +0 -69
- package/src/tools/search.ts +0 -181
- package/src/tools/timeline.ts +0 -64
- package/tsconfig.json +0 -22
package/README.md
CHANGED
|
@@ -1,121 +1,262 @@
|
|
|
1
1
|
# Engrm
|
|
2
2
|
|
|
3
|
-
**Cross-device memory for AI coding agents
|
|
3
|
+
**Cross-device memory for AI coding agents.** Every session remembers what you learned yesterday — on any machine, for every team member.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
```
|
|
6
|
+
npx engrm init
|
|
7
|
+
```
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## What It Does
|
|
12
|
+
|
|
13
|
+
Your AI agent forgets everything between sessions. Engrm fixes that.
|
|
14
|
+
|
|
15
|
+
- **Captures automatically** — hooks into Claude Code to record discoveries, bugfixes, decisions, and patterns as you work
|
|
16
|
+
- **Remembers across devices** — fix a bug on your laptop, continue on your desktop with full context
|
|
17
|
+
- **Shares with your team** — one developer's hard-won insight becomes everyone's knowledge
|
|
18
|
+
- **Works offline** — local SQLite is the source of truth; syncs when connected
|
|
19
|
+
- **Guards your code** — Sentinel audits changes in real-time before they land
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Sign up
|
|
24
|
+
|
|
25
|
+
Visit [engrm.dev](https://engrm.dev) and create an account.
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
### 2. Install
|
|
14
28
|
|
|
15
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npx engrm init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This opens your browser for authentication, writes config to `~/.engrm/`, and registers the MCP server + hooks in Claude Code. Takes about 30 seconds.
|
|
34
|
+
|
|
35
|
+
**Alternative methods:**
|
|
36
|
+
```bash
|
|
37
|
+
# From a provisioning token (shown on engrm.dev after signup)
|
|
38
|
+
npx engrm init --token=cmt_your_token
|
|
39
|
+
|
|
40
|
+
# Self-hosted Candengo Vector
|
|
41
|
+
npx engrm init --url=https://vector.internal.company.com
|
|
42
|
+
|
|
43
|
+
# Manual setup (air-gapped environments)
|
|
44
|
+
npx engrm init --manual
|
|
45
|
+
```
|
|
16
46
|
|
|
17
|
-
|
|
47
|
+
### 3. Use Claude Code normally
|
|
18
48
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
49
|
+
That's it. Engrm works in the background:
|
|
50
|
+
|
|
51
|
+
- **Session start** — injects relevant project memory into context
|
|
52
|
+
- **While you work** — captures observations from tool use (edits, writes, commands)
|
|
53
|
+
- **Session end** — generates a session digest, syncs to cloud, shows summary
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
━━━ Engrm Session Summary ━━━
|
|
57
|
+
|
|
58
|
+
📋 Request: Fix the OAuth redirect validation
|
|
59
|
+
🔍 Investigated: redirect_uri handling in auth.py
|
|
60
|
+
💡 Learned: scheme + host + port must all match registered URIs
|
|
61
|
+
✅ Completed: Stricter redirect_uri validation (auth.py)
|
|
62
|
+
|
|
63
|
+
🟢 Risk: Low (0.12)
|
|
64
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 4. Check status
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx engrm status
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Engrm Status
|
|
75
|
+
|
|
76
|
+
User: david
|
|
77
|
+
Email: david@example.com
|
|
78
|
+
Device: macbook-a1b2c3d4
|
|
79
|
+
Plan: Pro ($15/mo)
|
|
80
|
+
Candengo: https://www.candengo.com
|
|
81
|
+
MCP server: registered
|
|
82
|
+
Hooks: registered (6 hooks)
|
|
83
|
+
|
|
84
|
+
Observations: 1,247 active
|
|
85
|
+
By type: change: 412, discovery: 289, bugfix: 187, ...
|
|
86
|
+
Sentinel: enabled (advisory, 142/200 today)
|
|
87
|
+
Sync: push 2m ago, pull 5m ago
|
|
88
|
+
Security: 3 findings (1 high, 2 medium)
|
|
89
|
+
```
|
|
23
90
|
|
|
24
91
|
---
|
|
25
92
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
93
|
+
## How It Works
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Claude Code session
|
|
97
|
+
│
|
|
98
|
+
├─ SessionStart hook ──→ inject relevant memory into context
|
|
99
|
+
│
|
|
100
|
+
├─ PreToolUse hook ────→ Sentinel audits Edit/Write (optional)
|
|
101
|
+
│
|
|
102
|
+
├─ PostToolUse hook ───→ extract observations from tool results
|
|
103
|
+
│
|
|
104
|
+
├─ PreCompact hook ────→ re-inject memory before context compression
|
|
105
|
+
│
|
|
106
|
+
├─ ElicitationResult ──→ capture MCP form submissions
|
|
107
|
+
│
|
|
108
|
+
└─ Stop hook ──────────→ session digest + sync + summary
|
|
109
|
+
│
|
|
110
|
+
▼
|
|
111
|
+
Local SQLite (FTS5 + sqlite-vec)
|
|
112
|
+
│
|
|
113
|
+
▼ (sync every 30s)
|
|
114
|
+
Candengo Vector (cloud)
|
|
115
|
+
│
|
|
116
|
+
▼
|
|
117
|
+
Available on all your devices + team members
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### MCP Tools
|
|
121
|
+
|
|
122
|
+
The MCP server exposes tools that Claude can call directly:
|
|
123
|
+
|
|
124
|
+
| Tool | Purpose |
|
|
125
|
+
|------|---------|
|
|
126
|
+
| `search` | Find relevant observations from memory (hybrid FTS5 + vector) |
|
|
127
|
+
| `timeline` | Chronological context around an observation |
|
|
128
|
+
| `get_observations` | Fetch full details by ID |
|
|
129
|
+
| `save_observation` | Manually save something worth remembering |
|
|
130
|
+
| `install_pack` | Load a curated knowledge pack for your stack |
|
|
131
|
+
|
|
132
|
+
### Observation Types
|
|
133
|
+
|
|
134
|
+
| Type | What it captures |
|
|
135
|
+
|------|-----------------|
|
|
136
|
+
| `discovery` | Learning about existing systems or codebases |
|
|
137
|
+
| `bugfix` | Something was broken, now fixed |
|
|
138
|
+
| `decision` | Architectural or design choice with rationale |
|
|
139
|
+
| `change` | Meaningful modification (feature, config, docs) |
|
|
140
|
+
| `feature` | New capability or functionality |
|
|
141
|
+
| `refactor` | Code restructured without behavior change |
|
|
142
|
+
| `pattern` | Recurring issue or technique |
|
|
143
|
+
| `digest` | Session summary (auto-generated) |
|
|
53
144
|
|
|
54
145
|
---
|
|
55
146
|
|
|
56
|
-
##
|
|
147
|
+
## Features
|
|
57
148
|
|
|
58
|
-
|
|
149
|
+
### Hybrid Search
|
|
150
|
+
Local FTS5 + sqlite-vec (all-MiniLM-L6-v2, 384 dims) combined with Candengo Vector's BGE-M3 semantic search. Results merged via Reciprocal Rank Fusion.
|
|
151
|
+
|
|
152
|
+
### Sentinel — Real-Time Code Audit
|
|
153
|
+
LLM-powered review of every Edit/Write before it executes. Catches security issues, anti-patterns, and drift from team decisions.
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
⚠️ Sentinel: SQL query uses string concatenation instead of parameterized query
|
|
157
|
+
Rule: sql-injection
|
|
158
|
+
(Advisory mode — change allowed)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
5 built-in rule packs: `security`, `auth`, `api`, `react`, `database`.
|
|
59
162
|
|
|
60
163
|
```bash
|
|
61
|
-
npx engrm init
|
|
164
|
+
npx engrm sentinel init-rules # Install all rule packs
|
|
165
|
+
npx engrm sentinel rules # List available packs
|
|
62
166
|
```
|
|
63
167
|
|
|
64
|
-
|
|
168
|
+
### Starter Packs
|
|
169
|
+
Pre-loaded knowledge for your tech stack. Detected automatically on session start.
|
|
65
170
|
|
|
66
|
-
|
|
171
|
+
Available: `typescript-patterns`, `nextjs-patterns`, `node-security`, `python-django`, `react-gotchas`, `api-best-practices`, `web-security`
|
|
67
172
|
|
|
68
|
-
**Self-hosted**: Point at your own Candengo Vector instance:
|
|
69
173
|
```bash
|
|
70
|
-
npx engrm
|
|
174
|
+
npx engrm install-pack typescript-patterns
|
|
71
175
|
```
|
|
72
176
|
|
|
177
|
+
### Secret Scrubbing
|
|
178
|
+
Multi-layer regex scanning for API keys, passwords, tokens, and credentials. Sensitive content is redacted before storage and sync. Custom patterns configurable in `~/.engrm/settings.json`.
|
|
179
|
+
|
|
180
|
+
### Observation Lifecycle
|
|
181
|
+
Observations age gracefully: **active** (30 days, full weight) → **aging** (0.7x search weight) → **archived** (compacted into digests) → **purged** (after 12 months). Pinned observations never age.
|
|
182
|
+
|
|
73
183
|
---
|
|
74
184
|
|
|
75
|
-
##
|
|
185
|
+
## Pricing
|
|
186
|
+
|
|
187
|
+
| | Free | Vibe | Pro | Team |
|
|
188
|
+
|---|---|---|---|---|
|
|
189
|
+
| **Price** | $0 | $9/mo | $15/mo | £19/seat/mo |
|
|
190
|
+
| **Observations** | 5,000 | 25,000 | Unlimited | Unlimited |
|
|
191
|
+
| **Devices** | 1 | 3 | Unlimited | Unlimited |
|
|
192
|
+
| **Cloud sync** | ✓ | ✓ | ✓ | ✓ |
|
|
193
|
+
| **Sentinel** | — | Advisory (50/day) | Advisory (200/day) | Blocking (unlimited) |
|
|
194
|
+
| **Retention** | 30 days | 90 days | 1 year | Unlimited |
|
|
195
|
+
| **Team namespace** | — | — | — | ✓ |
|
|
76
196
|
|
|
77
|
-
|
|
197
|
+
Sign up at [engrm.dev](https://engrm.dev).
|
|
78
198
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
- `timeline` — chronological context around an observation
|
|
83
|
-
- `get_observations` — fetch full details by ID
|
|
84
|
-
- `save_observation` — manually save something worth remembering
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Self-Hosting
|
|
85
202
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
203
|
+
Point Engrm at your own [Candengo Vector](https://www.candengo.com) instance:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npx engrm init --url=https://vector.internal.company.com --token=cmt_...
|
|
207
|
+
```
|
|
90
208
|
|
|
91
|
-
|
|
209
|
+
Candengo Vector provides the backend: BGE-M3 hybrid search, multi-tenant namespaces, and team sync. See the [Candengo docs](https://www.candengo.com/docs) for deployment.
|
|
92
210
|
|
|
93
211
|
---
|
|
94
212
|
|
|
95
|
-
##
|
|
213
|
+
## Configuration
|
|
214
|
+
|
|
215
|
+
### User config: `~/.engrm/settings.json`
|
|
216
|
+
|
|
217
|
+
Created by `engrm init`. Contains API credentials, sync settings, search preferences, secret scrubbing patterns, and Sentinel configuration.
|
|
96
218
|
|
|
97
|
-
|
|
219
|
+
### Project config: `.engrm.json` (optional)
|
|
220
|
+
|
|
221
|
+
Place in your project root to override project identity for non-git projects:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"project_id": "internal/design-system",
|
|
226
|
+
"name": "Design System"
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Claude Code integration
|
|
231
|
+
|
|
232
|
+
Engrm auto-registers in:
|
|
233
|
+
- `~/.claude.json` — MCP server (`engrm`)
|
|
234
|
+
- `~/.claude/settings.json` — 6 lifecycle hooks
|
|
98
235
|
|
|
99
236
|
---
|
|
100
237
|
|
|
101
|
-
##
|
|
238
|
+
## Tech Stack
|
|
102
239
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
| [COMPETITIVE.md](COMPETITIVE.md) | Competitive landscape analysis |
|
|
110
|
-
| [MARKET.md](MARKET.md) | Market research, pricing, growth projections |
|
|
111
|
-
| [INFRASTRUCTURE.md](INFRASTRUCTURE.md) | Scaling roadmap, capacity planning |
|
|
240
|
+
- **Runtime**: TypeScript, runs on Bun (dev) or Node.js 18+ (npm)
|
|
241
|
+
- **Local storage**: SQLite via better-sqlite3, FTS5 full-text search, sqlite-vec for embeddings
|
|
242
|
+
- **Embeddings**: all-MiniLM-L6-v2 via @xenova/transformers (384 dims, ~23MB)
|
|
243
|
+
- **Remote backend**: Candengo Vector (BGE-M3, Qdrant, hybrid dense+sparse search)
|
|
244
|
+
- **MCP**: @modelcontextprotocol/sdk (stdio transport)
|
|
245
|
+
- **AI extraction**: @anthropic-ai/claude-agent-sdk (optional, for richer observations)
|
|
112
246
|
|
|
113
247
|
---
|
|
114
248
|
|
|
115
249
|
## License
|
|
116
250
|
|
|
117
|
-
|
|
251
|
+
**FSL-1.1-ALv2** (Functional Source License) — part of the [Fair Source](https://fair.io) movement.
|
|
252
|
+
|
|
253
|
+
- Free to use, modify, and self-host
|
|
254
|
+
- You cannot offer this as a competing hosted service
|
|
255
|
+
- Each version converts to Apache 2.0 after 2 years
|
|
256
|
+
- Sentinel is a separate proprietary product
|
|
257
|
+
|
|
258
|
+
See [LICENSE](LICENSE) for full terms.
|
|
118
259
|
|
|
119
260
|
---
|
|
120
261
|
|
|
121
|
-
Built by [Unimpossible Consultants](https://unimpossible.com) — the team behind Candengo, Alchemy, and AIMY.
|
|
262
|
+
Built by [Unimpossible Consultants](https://unimpossible.com) — the team behind [Candengo](https://www.candengo.com), Alchemy, and AIMY.
|
package/bin/build.mjs
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Build script — compiles TypeScript to Node.js-compatible JavaScript.
|
|
4
|
+
*
|
|
5
|
+
* Uses Bun's bundler to produce self-contained .js files that run on Node.js.
|
|
6
|
+
* Output goes to dist/ and is what gets published to npm.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { rmSync, mkdirSync, copyFileSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { join, dirname } from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const root = join(__dirname, "..");
|
|
15
|
+
const dist = join(root, "dist");
|
|
16
|
+
|
|
17
|
+
// Clean
|
|
18
|
+
rmSync(dist, { recursive: true, force: true });
|
|
19
|
+
mkdirSync(dist, { recursive: true });
|
|
20
|
+
mkdirSync(join(dist, "hooks"), { recursive: true });
|
|
21
|
+
|
|
22
|
+
console.log("Building Engrm for Node.js...\n");
|
|
23
|
+
|
|
24
|
+
// Build CLI + MCP server
|
|
25
|
+
const mainResult = await Bun.build({
|
|
26
|
+
entrypoints: [
|
|
27
|
+
join(root, "src/cli.ts"),
|
|
28
|
+
join(root, "src/server.ts"),
|
|
29
|
+
],
|
|
30
|
+
outdir: dist,
|
|
31
|
+
target: "node",
|
|
32
|
+
format: "esm",
|
|
33
|
+
external: [
|
|
34
|
+
"better-sqlite3",
|
|
35
|
+
"sqlite-vec",
|
|
36
|
+
"@xenova/transformers",
|
|
37
|
+
"@modelcontextprotocol/sdk",
|
|
38
|
+
"@anthropic-ai/claude-agent-sdk",
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!mainResult.success) {
|
|
43
|
+
console.error("Build failed (main):");
|
|
44
|
+
for (const msg of mainResult.logs) console.error(msg);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
console.log(" dist/cli.js");
|
|
48
|
+
console.log(" dist/server.js");
|
|
49
|
+
|
|
50
|
+
// Build hooks
|
|
51
|
+
const hookResult = await Bun.build({
|
|
52
|
+
entrypoints: [
|
|
53
|
+
join(root, "hooks/session-start.ts"),
|
|
54
|
+
join(root, "hooks/pre-compact.ts"),
|
|
55
|
+
join(root, "hooks/post-tool-use.ts"),
|
|
56
|
+
join(root, "hooks/stop.ts"),
|
|
57
|
+
join(root, "hooks/sentinel.ts"),
|
|
58
|
+
join(root, "hooks/elicitation-result.ts"),
|
|
59
|
+
],
|
|
60
|
+
outdir: join(dist, "hooks"),
|
|
61
|
+
target: "node",
|
|
62
|
+
format: "esm",
|
|
63
|
+
external: [
|
|
64
|
+
"better-sqlite3",
|
|
65
|
+
"sqlite-vec",
|
|
66
|
+
"@xenova/transformers",
|
|
67
|
+
"@modelcontextprotocol/sdk",
|
|
68
|
+
"@anthropic-ai/claude-agent-sdk",
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!hookResult.success) {
|
|
73
|
+
console.error("Build failed (hooks):");
|
|
74
|
+
for (const msg of hookResult.logs) console.error(msg);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
console.log(" dist/hooks/session-start.js");
|
|
78
|
+
console.log(" dist/hooks/pre-compact.js");
|
|
79
|
+
console.log(" dist/hooks/post-tool-use.js");
|
|
80
|
+
console.log(" dist/hooks/stop.js");
|
|
81
|
+
console.log(" dist/hooks/sentinel.js");
|
|
82
|
+
console.log(" dist/hooks/elicitation-result.js");
|
|
83
|
+
|
|
84
|
+
// Add Node.js shebang to CLI and hooks (strip any existing shebangs first)
|
|
85
|
+
async function addShebang(filePath) {
|
|
86
|
+
const raw = await Bun.file(filePath).text();
|
|
87
|
+
const stripped = raw.replace(/^#!.*\n/gm, "");
|
|
88
|
+
writeFileSync(filePath, `#!/usr/bin/env node\n${stripped}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
await addShebang(join(dist, "cli.js"));
|
|
92
|
+
await addShebang(join(dist, "server.js"));
|
|
93
|
+
for (const hook of ["session-start", "pre-compact", "post-tool-use", "stop", "sentinel", "elicitation-result"]) {
|
|
94
|
+
await addShebang(join(dist, "hooks", `${hook}.js`));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log("\nBuild complete.");
|
package/bin/engrm.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Engrm CLI entry point for npm/npx.
|
|
4
|
+
* Runs the pre-built dist/cli.js on Node.js — no Bun required.
|
|
5
|
+
*/
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// Import and run the built CLI
|
|
13
|
+
await import(join(__dirname, "..", "dist", "cli.js"));
|