dude-claude-plugin 2026.2.1 → 2026.2.2
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/plugin.json +15 -0
- package/.mcp.json +8 -8
- package/LICENSE +21 -0
- package/README.md +80 -57
- package/bin/dude-claude.js +23 -23
- package/hooks/auto-persist.js +59 -59
- package/hooks/auto-retrieve.js +46 -46
- package/hooks.json +26 -0
- package/package.json +52 -24
- package/src/db.js +260 -260
- package/src/embed.js +23 -23
- package/src/migrations/001-initial.js +30 -30
- package/src/server.js +134 -134
- package/src/web.js +180 -180
- package/web/index.html +346 -346
- package/.claude/settings.local.json +0 -38
- package/doc/SPEC.md +0 -322
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dude-claude-plugin",
|
|
3
|
+
"version": "2026.2.1",
|
|
4
|
+
"description": "Ultra-minimal RAG and cross-project memory for Claude CLI",
|
|
5
|
+
"author": { "name": "Fingerskier" },
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": ["rag", "memory", "project-context", "issues", "specifications"],
|
|
8
|
+
"hooks": "./hooks.json",
|
|
9
|
+
"mcpServers": {
|
|
10
|
+
"dude": {
|
|
11
|
+
"command": "node",
|
|
12
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/bin/dude-claude.js", "mcp"]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/.mcp.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mcpServers": {
|
|
3
|
-
"dude": {
|
|
4
|
-
"command": "node",
|
|
5
|
-
"args": ["bin/dude-claude.js", "mcp"]
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"dude": {
|
|
4
|
+
"command": "node",
|
|
5
|
+
"args": ["bin/dude-claude.js", "mcp"]
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fingerskier
|
|
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,57 +1,80 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
###
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
# dude-claude-plugin
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/dude-claude-plugin)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
Ultra-minimal RAG and cross-project memory for Claude Code.
|
|
7
|
+
|
|
8
|
+
Dude gives Claude a persistent memory across projects. It stores issues and specifications in a local SQLite database with vector embeddings, so Claude automatically recalls relevant context from past sessions.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
### From marketplace (recommended)
|
|
13
|
+
|
|
14
|
+
Installs MCP tools **and** hooks (auto-retrieve on prompt, auto-persist on stop):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
claude plugin marketplace add fingerskier/claude-plugins
|
|
18
|
+
claude plugin install dude-claude-plugin@fingerskier-plugins
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### MCP server only (via npx)
|
|
22
|
+
|
|
23
|
+
If you just want the 6 MCP tools without auto-hooks:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
claude mcp add dude -- npx dude-claude-plugin mcp
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Global install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g dude-claude-plugin
|
|
33
|
+
claude mcp add dude -- dude-claude mcp
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## What it does
|
|
37
|
+
|
|
38
|
+
| Component | Description |
|
|
39
|
+
|-----------|-------------|
|
|
40
|
+
| **MCP server** | 6 tools: `search`, `upsert_record`, `get_record`, `list_records`, `delete_record`, `list_projects` |
|
|
41
|
+
| **Auto-retrieve hook** | On each prompt, searches memory for relevant context and injects it |
|
|
42
|
+
| **Auto-persist hook** | After each response, classifies the work and saves issues/specs |
|
|
43
|
+
| **Web UI** | Local dashboard at `http://127.0.0.1:3456` for manual CRUD |
|
|
44
|
+
| **Storage** | SQLite + sqlite-vec at `~/.dude-claude/dude.db` |
|
|
45
|
+
| **Embeddings** | Local all-MiniLM-L6-v2 via @huggingface/transformers (no API keys) |
|
|
46
|
+
|
|
47
|
+
## How it works
|
|
48
|
+
|
|
49
|
+
1. You submit a prompt -- the auto-retrieve hook embeds it and searches for related records across all your projects
|
|
50
|
+
2. Matching context is injected so Claude has relevant history before reasoning
|
|
51
|
+
3. After Claude responds, the auto-persist hook classifies the work:
|
|
52
|
+
- Bug fix? Upserts an `issue` record (status: resolved)
|
|
53
|
+
- Improvement? Upserts a `spec` record
|
|
54
|
+
- Neither? Skips silently
|
|
55
|
+
4. Next session, step 1 finds those records automatically
|
|
56
|
+
|
|
57
|
+
## Web UI
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx dude-claude-plugin serve
|
|
61
|
+
# or if globally installed:
|
|
62
|
+
dude-claude serve
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Opens a local dashboard on port 3456 for browsing and editing projects, issues, and specifications.
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
| Env variable | Default | Description |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `DUDE_PORT` | `3456` | Web UI port |
|
|
72
|
+
| `DUDE_CONTEXT_LIMIT` | `5` | Max records injected per prompt |
|
|
73
|
+
|
|
74
|
+
## Requirements
|
|
75
|
+
|
|
76
|
+
- Node.js >= 18
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
[MIT](./LICENSE)
|
package/bin/dude-claude.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const command = process.argv[2] || 'mcp';
|
|
4
|
-
|
|
5
|
-
switch (command) {
|
|
6
|
-
case 'mcp': {
|
|
7
|
-
const { startServer } = await import('../src/server.js');
|
|
8
|
-
await startServer();
|
|
9
|
-
break;
|
|
10
|
-
}
|
|
11
|
-
case 'serve': {
|
|
12
|
-
const { startWebServer } = await import('../src/web.js');
|
|
13
|
-
await startWebServer();
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
default:
|
|
17
|
-
console.error(`Usage: dude-claude [mcp|serve]
|
|
18
|
-
|
|
19
|
-
Commands:
|
|
20
|
-
mcp Start the MCP stdio server (default)
|
|
21
|
-
serve Start the web UI server on http://127.0.0.1:${process.env.DUDE_PORT || 3456}`);
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const command = process.argv[2] || 'mcp';
|
|
4
|
+
|
|
5
|
+
switch (command) {
|
|
6
|
+
case 'mcp': {
|
|
7
|
+
const { startServer } = await import('../src/server.js');
|
|
8
|
+
await startServer();
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
case 'serve': {
|
|
12
|
+
const { startWebServer } = await import('../src/web.js');
|
|
13
|
+
await startWebServer();
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
default:
|
|
17
|
+
console.error(`Usage: dude-claude [mcp|serve]
|
|
18
|
+
|
|
19
|
+
Commands:
|
|
20
|
+
mcp Start the MCP stdio server (default)
|
|
21
|
+
serve Start the web UI server on http://127.0.0.1:${process.env.DUDE_PORT || 3456}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
package/hooks/auto-persist.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stop hook — auto-persist records from conversation classification.
|
|
5
|
-
* Reads classification JSON from stdin, upserts records as needed.
|
|
6
|
-
* On malformed JSON or action=none, exits silently.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { embed } from '../src/embed.js';
|
|
10
|
-
import { initDb, upsertRecord, getCurrentProject } from '../src/db.js';
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
const chunks = [];
|
|
14
|
-
for await (const chunk of process.stdin) {
|
|
15
|
-
chunks.push(chunk);
|
|
16
|
-
}
|
|
17
|
-
const raw = Buffer.concat(chunks).toString().trim();
|
|
18
|
-
|
|
19
|
-
let input;
|
|
20
|
-
try {
|
|
21
|
-
input = JSON.parse(raw);
|
|
22
|
-
} catch {
|
|
23
|
-
process.stdout.write('Auto-persist skipped: malformed JSON from classification prompt\n');
|
|
24
|
-
process.exit(0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!input.action || input.action === 'none') {
|
|
28
|
-
process.exit(0);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (input.action === 'upsert') {
|
|
32
|
-
const kind = input.kind || 'issue';
|
|
33
|
-
const title = input.title || 'Untitled';
|
|
34
|
-
const body = input.body || '';
|
|
35
|
-
const status = input.status || 'open';
|
|
36
|
-
|
|
37
|
-
await initDb();
|
|
38
|
-
const text = `${title} ${body}`.trim();
|
|
39
|
-
const embedding = await embed(text);
|
|
40
|
-
|
|
41
|
-
const record = upsertRecord(
|
|
42
|
-
{
|
|
43
|
-
projectId: getCurrentProject().id,
|
|
44
|
-
kind,
|
|
45
|
-
title,
|
|
46
|
-
body,
|
|
47
|
-
status,
|
|
48
|
-
},
|
|
49
|
-
embedding,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
process.stdout.write(`Auto-persisted ${kind}: "${record.title}" (id=${record.id})\n`);
|
|
53
|
-
}
|
|
54
|
-
} catch (err) {
|
|
55
|
-
// Non-blocking: exit cleanly on any error
|
|
56
|
-
console.error(`[dude] auto-persist error: ${err.message}`);
|
|
57
|
-
process.stdout.write(`Auto-persist skipped: ${err.message}\n`);
|
|
58
|
-
process.exit(0);
|
|
59
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stop hook — auto-persist records from conversation classification.
|
|
5
|
+
* Reads classification JSON from stdin, upserts records as needed.
|
|
6
|
+
* On malformed JSON or action=none, exits silently.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { embed } from '../src/embed.js';
|
|
10
|
+
import { initDb, upsertRecord, getCurrentProject } from '../src/db.js';
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
for await (const chunk of process.stdin) {
|
|
15
|
+
chunks.push(chunk);
|
|
16
|
+
}
|
|
17
|
+
const raw = Buffer.concat(chunks).toString().trim();
|
|
18
|
+
|
|
19
|
+
let input;
|
|
20
|
+
try {
|
|
21
|
+
input = JSON.parse(raw);
|
|
22
|
+
} catch {
|
|
23
|
+
process.stdout.write('Auto-persist skipped: malformed JSON from classification prompt\n');
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!input.action || input.action === 'none') {
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (input.action === 'upsert') {
|
|
32
|
+
const kind = input.kind || 'issue';
|
|
33
|
+
const title = input.title || 'Untitled';
|
|
34
|
+
const body = input.body || '';
|
|
35
|
+
const status = input.status || 'open';
|
|
36
|
+
|
|
37
|
+
await initDb();
|
|
38
|
+
const text = `${title} ${body}`.trim();
|
|
39
|
+
const embedding = await embed(text);
|
|
40
|
+
|
|
41
|
+
const record = upsertRecord(
|
|
42
|
+
{
|
|
43
|
+
projectId: getCurrentProject().id,
|
|
44
|
+
kind,
|
|
45
|
+
title,
|
|
46
|
+
body,
|
|
47
|
+
status,
|
|
48
|
+
},
|
|
49
|
+
embedding,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
process.stdout.write(`Auto-persisted ${kind}: "${record.title}" (id=${record.id})\n`);
|
|
53
|
+
}
|
|
54
|
+
} catch (err) {
|
|
55
|
+
// Non-blocking: exit cleanly on any error
|
|
56
|
+
console.error(`[dude] auto-persist error: ${err.message}`);
|
|
57
|
+
process.stdout.write(`Auto-persist skipped: ${err.message}\n`);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
package/hooks/auto-retrieve.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* UserPromptSubmit hook — auto-retrieve relevant records.
|
|
5
|
-
* Reads the user prompt from stdin JSON, embeds it, searches the DB,
|
|
6
|
-
* and writes formatted context to stdout for Claude to see.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { embed } from '../src/embed.js';
|
|
10
|
-
import { initDb, searchRecords } from '../src/db.js';
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
const chunks = [];
|
|
14
|
-
for await (const chunk of process.stdin) {
|
|
15
|
-
chunks.push(chunk);
|
|
16
|
-
}
|
|
17
|
-
const input = JSON.parse(Buffer.concat(chunks).toString());
|
|
18
|
-
const prompt = input.prompt || input.tool_input?.prompt || '';
|
|
19
|
-
|
|
20
|
-
if (!prompt.trim()) {
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
await initDb();
|
|
25
|
-
const embedding = await embed(prompt);
|
|
26
|
-
const limit = Number(process.env.DUDE_CONTEXT_LIMIT) || 5;
|
|
27
|
-
const results = searchRecords(embedding, { limit });
|
|
28
|
-
|
|
29
|
-
if (results.length === 0) {
|
|
30
|
-
process.exit(0);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Format context for Claude
|
|
34
|
-
const lines = ['[dude] Relevant context from memory:\n'];
|
|
35
|
-
for (const r of results) {
|
|
36
|
-
lines.push(`- [${r.kind}] ${r.title} (project: ${r.project}, status: ${r.status}, similarity: ${r.similarity.toFixed(2)})`);
|
|
37
|
-
if (r.body) {
|
|
38
|
-
lines.push(` ${r.body.slice(0, 200)}${r.body.length > 200 ? '…' : ''}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
process.stdout.write(lines.join('\n') + '\n');
|
|
42
|
-
} catch (err) {
|
|
43
|
-
// Non-blocking: exit cleanly on any error
|
|
44
|
-
console.error(`[dude] auto-retrieve error: ${err.message}`);
|
|
45
|
-
process.exit(0);
|
|
46
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* UserPromptSubmit hook — auto-retrieve relevant records.
|
|
5
|
+
* Reads the user prompt from stdin JSON, embeds it, searches the DB,
|
|
6
|
+
* and writes formatted context to stdout for Claude to see.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { embed } from '../src/embed.js';
|
|
10
|
+
import { initDb, searchRecords } from '../src/db.js';
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
for await (const chunk of process.stdin) {
|
|
15
|
+
chunks.push(chunk);
|
|
16
|
+
}
|
|
17
|
+
const input = JSON.parse(Buffer.concat(chunks).toString());
|
|
18
|
+
const prompt = input.prompt || input.tool_input?.prompt || '';
|
|
19
|
+
|
|
20
|
+
if (!prompt.trim()) {
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
await initDb();
|
|
25
|
+
const embedding = await embed(prompt);
|
|
26
|
+
const limit = Number(process.env.DUDE_CONTEXT_LIMIT) || 5;
|
|
27
|
+
const results = searchRecords(embedding, { limit });
|
|
28
|
+
|
|
29
|
+
if (results.length === 0) {
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Format context for Claude
|
|
34
|
+
const lines = ['[dude] Relevant context from memory:\n'];
|
|
35
|
+
for (const r of results) {
|
|
36
|
+
lines.push(`- [${r.kind}] ${r.title} (project: ${r.project}, status: ${r.status}, similarity: ${r.similarity.toFixed(2)})`);
|
|
37
|
+
if (r.body) {
|
|
38
|
+
lines.push(` ${r.body.slice(0, 200)}${r.body.length > 200 ? '…' : ''}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
42
|
+
} catch (err) {
|
|
43
|
+
// Non-blocking: exit cleanly on any error
|
|
44
|
+
console.error(`[dude] auto-retrieve error: ${err.message}`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
package/hooks.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"UserPromptSubmit": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/auto-retrieve.js",
|
|
9
|
+
"timeout": 30
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"Stop": [
|
|
15
|
+
{
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/auto-persist.js",
|
|
20
|
+
"timeout": 30
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dude-claude-plugin",
|
|
3
|
-
"version": "2026.2.
|
|
4
|
-
"description": "Ultra-minimal RAG and cross-project memory for Claude CLI",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"dude-claude": "bin/dude-claude.js"
|
|
8
|
-
},
|
|
9
|
-
"engines": {
|
|
10
|
-
"node": ">=18"
|
|
11
|
-
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"start": "node bin/dude-claude.js mcp",
|
|
14
|
-
"serve": "node bin/dude-claude.js serve"
|
|
15
|
-
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "dude-claude-plugin",
|
|
3
|
+
"version": "2026.2.2",
|
|
4
|
+
"description": "Ultra-minimal RAG and cross-project memory for Claude CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dude-claude": "bin/dude-claude.js"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"start": "node bin/dude-claude.js mcp",
|
|
14
|
+
"serve": "node bin/dude-claude.js serve"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"claude",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"plugin",
|
|
20
|
+
"mcp",
|
|
21
|
+
"rag",
|
|
22
|
+
"memory",
|
|
23
|
+
"knowledge-base",
|
|
24
|
+
"vector-search"
|
|
25
|
+
],
|
|
26
|
+
"author": "Fingerskier",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/fingerskier/dude-claude-plugin.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/fingerskier/dude-claude-plugin#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/fingerskier/dude-claude-plugin/issues"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"bin/",
|
|
37
|
+
"src/",
|
|
38
|
+
"hooks/",
|
|
39
|
+
"web/",
|
|
40
|
+
".claude-plugin/",
|
|
41
|
+
".mcp.json",
|
|
42
|
+
"hooks.json"
|
|
43
|
+
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
46
|
+
"zod": "^3.24.2",
|
|
47
|
+
"better-sqlite3": "^11.8.1",
|
|
48
|
+
"sqlite-vec": "^0.1.6",
|
|
49
|
+
"@huggingface/transformers": "^3.4.1"
|
|
50
|
+
},
|
|
51
|
+
"license": "MIT"
|
|
52
|
+
}
|