@heretek-ai/epistemic-swarm 0.2.0 → 0.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/marketplace.json +36 -9
- package/.claude-plugin/plugin.json +47 -41
- package/MARKETPLACE.md +93 -0
- package/README.md +39 -2
- package/bin/cli.js +58 -0
- package/config/mcp_launcher.py +215 -0
- package/hooks/hooks.json +24 -0
- package/package.json +26 -3
- package/plugins/research-cache/.claude-plugin/plugin.json +15 -0
- package/plugins/socratic-grilling/.claude-plugin/plugin.json +15 -0
- package/plugins/socratic-grilling/skills/grilling/SKILL.md +48 -0
- package/plugins/socratic-grilling/skills/grilling/__init__.py +0 -0
- package/plugins/socratic-grilling/skills/grilling/socratic_tree.py +148 -0
- package/prompts/agent_code_auditor.md +88 -0
- package/prompts/agent_oss_scout.md +78 -0
- package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
- package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
- package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
- package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
- package/runner/research_swarm.py +230 -81
- package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
- package/runner/tests/test_swarm.py +37 -0
- package/skills/code_audit/SKILL.md +45 -0
- package/skills/epistemic_search/SKILL.md +35 -0
- package/skills/epistemic_search/__init__.py +1 -0
- package/skills/epistemic_search/scripts/fetch.py +157 -0
- package/skills/epistemic_search/scripts/search.py +162 -0
- package/skills/oss_scout/SKILL.md +49 -0
- package/skills/research_cache/SKILL.md +36 -0
- package/skills/research_cache/__init__.py +0 -0
- package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/{research-cache → research_cache}/__pycache__/hasher.cpython-311.pyc +0 -0
- package/skills/research_cache/hasher.py +195 -0
- package/skills/swarm_config/SKILL.md +72 -0
- package/skills/swarm_config/__init__.py +4 -0
- package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
- package/skills/swarm_config/configure.py +167 -0
- package/skills/research-cache/__pycache__/__init__.cpython-311.pyc +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/SKILL.md +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/__init__.py +0 -0
- /package/{skills/research-cache → plugins/research-cache/skills/research_cache}/hasher.py +0 -0
|
@@ -1,14 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
2
3
|
"name": "heretek-official",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
"description": "Official high-integrity research agents and epistemic skills from Heretek AI",
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": "Heretek AI",
|
|
7
|
+
"email": "dev@heretek.ai"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "epistemic-swarm",
|
|
12
|
+
"description": "High-Integrity Dialectic Research Agent Harness enforcing verified empirical evidence over parametric hallucination.",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Heretek AI"
|
|
10
15
|
},
|
|
11
|
-
"
|
|
16
|
+
"category": "research",
|
|
17
|
+
"source": "./",
|
|
18
|
+
"homepage": "https://github.com/Heretek-AI/IUMBTEMS"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "socratic-grilling",
|
|
22
|
+
"description": "Matt Pocock-style Socratic interrogation, premise inversion, and lateral exploration skill for Claude Code.",
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "Heretek AI"
|
|
25
|
+
},
|
|
26
|
+
"category": "agents",
|
|
27
|
+
"source": "./plugins/socratic-grilling",
|
|
28
|
+
"homepage": "https://github.com/Heretek-AI/IUMBTEMS"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "research-cache",
|
|
32
|
+
"description": "Content-addressed SHA256 Markdown source hashing and verbatim quote verification engine.",
|
|
33
|
+
"author": {
|
|
34
|
+
"name": "Heretek AI"
|
|
35
|
+
},
|
|
36
|
+
"category": "research",
|
|
37
|
+
"source": "./plugins/research-cache",
|
|
38
|
+
"homepage": "https://github.com/Heretek-AI/IUMBTEMS"
|
|
12
39
|
}
|
|
13
|
-
|
|
40
|
+
]
|
|
14
41
|
}
|
|
@@ -1,58 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epistemic-swarm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "High-Integrity Dialectic Research Agent Harness for Claude Code enforcing empirical evidence over parametric hallucination.",
|
|
5
|
-
"author":
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Heretek AI",
|
|
7
|
+
"email": "dev@heretek.ai"
|
|
8
|
+
},
|
|
6
9
|
"license": "Apache-2.0",
|
|
7
10
|
"repository": "https://github.com/Heretek-AI/IUMBTEMS",
|
|
11
|
+
"homepage": "https://github.com/Heretek-AI/IUMBTEMS#readme",
|
|
12
|
+
"userConfig": {
|
|
13
|
+
"brave_api_key": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"title": "Brave Search API Key",
|
|
16
|
+
"description": "API key for Brave Search discovery (optional; zero-key DuckDuckGo fallback is used when unset)",
|
|
17
|
+
"sensitive": true,
|
|
18
|
+
"required": false
|
|
19
|
+
},
|
|
20
|
+
"firecrawl_api_key": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"title": "Firecrawl API Key",
|
|
23
|
+
"description": "API key for Firecrawl deep web extraction (optional; zero-key readability fallback is used when unset)",
|
|
24
|
+
"sensitive": true,
|
|
25
|
+
"required": false
|
|
26
|
+
},
|
|
27
|
+
"firecrawl_api_url": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"title": "Firecrawl API URL",
|
|
30
|
+
"description": "Endpoint for Firecrawl API or self-hosted instance",
|
|
31
|
+
"default": "https://api.firecrawl.dev",
|
|
32
|
+
"required": false
|
|
33
|
+
},
|
|
34
|
+
"searxng_url": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"title": "SearXNG URL",
|
|
37
|
+
"description": "Endpoint for self-hosted SearXNG metasearch instance",
|
|
38
|
+
"default": "http://localhost:8080",
|
|
39
|
+
"required": false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
8
42
|
"mcpServers": {
|
|
9
43
|
"brave-search": {
|
|
10
|
-
"command": "
|
|
11
|
-
"args": ["
|
|
12
|
-
"env": {
|
|
13
|
-
"BRAVE_SEARCH_API_KEY": "${BRAVE_SEARCH_API_KEY}"
|
|
14
|
-
}
|
|
44
|
+
"command": "python3",
|
|
45
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/config/mcp_launcher.py", "brave-search"]
|
|
15
46
|
},
|
|
16
47
|
"firecrawl": {
|
|
17
|
-
"command": "
|
|
18
|
-
"args": ["
|
|
19
|
-
"env": {
|
|
20
|
-
"FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}",
|
|
21
|
-
"FIRECRAWL_API_URL": "${FIRECRAWL_API_URL:-http://localhost:3002}"
|
|
22
|
-
}
|
|
48
|
+
"command": "python3",
|
|
49
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/config/mcp_launcher.py", "firecrawl"]
|
|
23
50
|
},
|
|
24
51
|
"searxng": {
|
|
25
52
|
"command": "python3",
|
|
26
|
-
"args": ["${
|
|
27
|
-
"env": {
|
|
28
|
-
"SEARXNG_URL": "${SEARXNG_URL:-http://localhost:8080}"
|
|
29
|
-
}
|
|
53
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/config/mcp_launcher.py", "searxng"]
|
|
30
54
|
}
|
|
31
55
|
},
|
|
32
56
|
"skills": [
|
|
33
57
|
"./skills/grilling",
|
|
34
|
-
"./skills/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"default": "http://localhost:8080"
|
|
41
|
-
},
|
|
42
|
-
"FIRECRAWL_API_URL": {
|
|
43
|
-
"type": "string",
|
|
44
|
-
"description": "Firecrawl API endpoint for JS/Markdown extraction",
|
|
45
|
-
"default": "http://localhost:3002"
|
|
46
|
-
},
|
|
47
|
-
"FIRECRAWL_API_KEY": {
|
|
48
|
-
"type": "string",
|
|
49
|
-
"description": "Firecrawl API Key (optional for self-hosted instances)",
|
|
50
|
-
"default": ""
|
|
51
|
-
},
|
|
52
|
-
"BRAVE_SEARCH_API_KEY": {
|
|
53
|
-
"type": "string",
|
|
54
|
-
"description": "Brave Search API Key for discovery",
|
|
55
|
-
"default": ""
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
+
"./skills/research_cache",
|
|
59
|
+
"./skills/epistemic_search",
|
|
60
|
+
"./skills/swarm_config",
|
|
61
|
+
"./skills/code_audit",
|
|
62
|
+
"./skills/oss_scout"
|
|
63
|
+
]
|
|
58
64
|
}
|
package/MARKETPLACE.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Heretek AI Claude Code Marketplace 🏪
|
|
2
|
+
|
|
3
|
+
Official marketplace catalog for Claude Code plugins, skills, and autonomous agent harnesses developed by [Heretek AI](https://github.com/Heretek-AI).
|
|
4
|
+
|
|
5
|
+
[](https://claude.com)
|
|
6
|
+
[](https://github.com/Heretek-AI/IUMBTEMS/actions/workflows/validate-marketplace.yml)
|
|
7
|
+
[](https://www.npmjs.com/package/@heretek-ai/epistemic-swarm)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🚀 Quick Start: Adding the Marketplace
|
|
12
|
+
|
|
13
|
+
To register the **`heretek-official`** marketplace in Claude Code, run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
claude plugin marketplace add Heretek-AI/IUMBTEMS
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Verify that the marketplace is configured:
|
|
20
|
+
```bash
|
|
21
|
+
claude plugin marketplace list
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 📦 Available Plugins
|
|
27
|
+
|
|
28
|
+
| Plugin Name | Category | Description | Install Command |
|
|
29
|
+
|---|---|---|---|
|
|
30
|
+
| **`epistemic-swarm`** | `research` | **Flagship Swarm Harness**: Multi-agent dialectic research harness pairing Agent Alpha (Thesis) against Agent Beta (Red Team), audited by an Epistemic Auditor with verbatim empirical quote validation. | `claude plugin install epistemic-swarm@heretek-official` |
|
|
31
|
+
| **`socratic-grilling`** | `agents` | **Socratic Ideation**: Matt Pocock-style Socratic interrogation, premise inversion, and lateral exploration skill. | `claude plugin install socratic-grilling@heretek-official` |
|
|
32
|
+
| **`research-cache`** | `research` | **Source Hasher**: Content-addressed SHA256 Markdown source hashing and verbatim quote verification engine. | `claude plugin install research-cache@heretek-official` |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🛠️ Plugin Details & Component Breakdown
|
|
37
|
+
|
|
38
|
+
### 1. `epistemic-swarm` (Flagship Harness)
|
|
39
|
+
- **Manifest**: [`.claude-plugin/plugin.json`](file:///.claude-plugin/plugin.json)
|
|
40
|
+
- **Components**:
|
|
41
|
+
- **Skills**: `skills/grilling`, `skills/research_cache`, `skills/epistemic_search`
|
|
42
|
+
- **Hooks**: `hooks/hooks.json` (`PreToolUse` hook intercepting ungrounded `WebSearch` and `WebFetch` to enforce verifiable SHA-256 caching)
|
|
43
|
+
- **Zero-Key Search**: DuckDuckGo Lite search and automated content-addressed document caching out of the box (zero API key required).
|
|
44
|
+
- **Safe MCP Servers & Accelerators**:
|
|
45
|
+
- `brave-search`: Optional Brave SERP discovery (falls back smoothly to DuckDuckGo when unconfigured).
|
|
46
|
+
- `firecrawl`: Optional Firecrawl JS extraction (falls back smoothly to clean readability reader when unconfigured).
|
|
47
|
+
- `searxng`: Optional self-hosted metasearch instance proxy.
|
|
48
|
+
- **System Prompts**: Base Epistemic System Override, Agent Alpha, Agent Beta, Epistemic Auditor, Orchestrator.
|
|
49
|
+
- **Install & Configuration**:
|
|
50
|
+
```bash
|
|
51
|
+
claude plugin install epistemic-swarm@heretek-official
|
|
52
|
+
# Configure optional API keys and endpoints interactively:
|
|
53
|
+
claude plugin configure epistemic-swarm
|
|
54
|
+
# Or inside Claude Code interactive session: /plugin configure
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 2. `socratic-grilling` (Modular Skill)
|
|
58
|
+
- **Manifest**: [`plugins/socratic-grilling/.claude-plugin/plugin.json`](file:///plugins/socratic-grilling/.claude-plugin/plugin.json)
|
|
59
|
+
- **Components**:
|
|
60
|
+
- **Skill**: `skills/grilling` (`/grilling` slash command and interactive decision tree).
|
|
61
|
+
- **Install**:
|
|
62
|
+
```bash
|
|
63
|
+
claude plugin install socratic-grilling@heretek-official
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. `research-cache` (Modular Tool)
|
|
67
|
+
- **Manifest**: [`plugins/research-cache/.claude-plugin/plugin.json`](file:///plugins/research-cache/.claude-plugin/plugin.json)
|
|
68
|
+
- **Components**:
|
|
69
|
+
- **Skill & Engine**: `skills/research-cache` (Content-addressed SHA256 raw source storage and quote validation).
|
|
70
|
+
- **Install**:
|
|
71
|
+
```bash
|
|
72
|
+
claude plugin install research-cache@heretek-official
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🔍 Inspecting Installed Plugins
|
|
78
|
+
|
|
79
|
+
To view installed plugins and their active components:
|
|
80
|
+
```bash
|
|
81
|
+
claude plugin list
|
|
82
|
+
claude plugin details epistemic-swarm@heretek-official
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
To update all installed plugins to their latest versions:
|
|
86
|
+
```bash
|
|
87
|
+
claude plugin update epistemic-swarm
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To uninstall:
|
|
91
|
+
```bash
|
|
92
|
+
claude plugin uninstall epistemic-swarm
|
|
93
|
+
```
|
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@heretek-ai/epistemic-swarm)
|
|
4
4
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
5
|
[](https://github.com/Heretek-AI/IUMBTEMS/actions)
|
|
6
|
+
[](https://github.com/Heretek-AI/IUMBTEMS/actions)
|
|
6
7
|
|
|
7
8
|
> **High-Integrity Dialectic Research Agent Harness**
|
|
8
9
|
> *Universal support for Claude Code, Pi (pi.dev), and OpenCode V2.*
|
|
@@ -27,8 +28,26 @@ Modern LLMs suffer from parametric hallucination, sycophancy, and premature narr
|
|
|
27
28
|
|
|
28
29
|
IUMBTEMS is packaged as a single universal npm package (`@heretek-ai/epistemic-swarm` with `iumbtems` binary) that runs across the three major autonomous agent platforms:
|
|
29
30
|
|
|
30
|
-
### 1. Claude Code
|
|
31
|
-
|
|
31
|
+
### 1. Claude Code (Native Marketplace & Overlay)
|
|
32
|
+
|
|
33
|
+
#### Native Marketplace (Recommended)
|
|
34
|
+
Add the official Heretek AI marketplace to Claude Code:
|
|
35
|
+
```bash
|
|
36
|
+
claude plugin marketplace add Heretek-AI/IUMBTEMS
|
|
37
|
+
```
|
|
38
|
+
Then install either the flagship harness or modular standalone plugins:
|
|
39
|
+
```bash
|
|
40
|
+
# Flagship dialectic research harness:
|
|
41
|
+
claude plugin install epistemic-swarm@heretek-official
|
|
42
|
+
|
|
43
|
+
# Or install standalone modular plugins:
|
|
44
|
+
claude plugin install socratic-grilling@heretek-official
|
|
45
|
+
claude plugin install research-cache@heretek-official
|
|
46
|
+
```
|
|
47
|
+
See [MARKETPLACE.md](MARKETPLACE.md) for full component specifications.
|
|
48
|
+
|
|
49
|
+
#### CLI Overlay Installer
|
|
50
|
+
Install skills and MCP servers directly into `~/.claude/` and `~/.claude.json`:
|
|
32
51
|
```bash
|
|
33
52
|
npx @heretek-ai/epistemic-swarm install
|
|
34
53
|
# or from local repo:
|
|
@@ -69,6 +88,16 @@ OpenCode V2 automatically registers:
|
|
|
69
88
|
## ⚡ CLI Command Reference
|
|
70
89
|
|
|
71
90
|
```bash
|
|
91
|
+
# Inspect or update active configuration (search engine, depth, mode)
|
|
92
|
+
iumbtems config
|
|
93
|
+
iumbtems config --engine duckduckgo --depth 3 --mode audit
|
|
94
|
+
|
|
95
|
+
# Run dialectic codebase architecture & security audit
|
|
96
|
+
iumbtems audit "runner/ and skills/ concurrency and injection security"
|
|
97
|
+
|
|
98
|
+
# Scout open-source software, mature libraries & clean-room blueprints
|
|
99
|
+
iumbtems scout "Zero-dependency Raft consensus implementations in Rust"
|
|
100
|
+
|
|
72
101
|
# Run the autonomous dialectic research swarm
|
|
73
102
|
iumbtems run "Sub-millisecond ZK state updates on L1 rollups"
|
|
74
103
|
|
|
@@ -82,6 +111,14 @@ iumbtems doctor
|
|
|
82
111
|
iumbtems test
|
|
83
112
|
```
|
|
84
113
|
|
|
114
|
+
### Specialized Dialectic Skills & Slash Commands
|
|
115
|
+
- **`/swarm-config`**: Interactive tuning of search engines (DuckDuckGo, Brave, Firecrawl, SearXNG), iteration depth, divergence thresholds, and operating modes.
|
|
116
|
+
- **`/code-audit`**: Dialectic codebase review pairing a Structural Architect (thesis) with a Vulnerability Red-Teamer (antithesis) enforcing line-number proofs (`file:///path#L10-25`).
|
|
117
|
+
- **`/oss-scout`**: Evaluates GitHub repositories, package ecosystems (npm, crates.io, PyPI), license contamination (GPL/AGPL copyleft vs MIT/Apache), and outputs clean-room re-implementation blueprints.
|
|
118
|
+
- **`/grilling`**: Socratic assumption-inversion and Matt Pocock-style design tree frontier discovery.
|
|
119
|
+
- **`epistemic_search`**: Zero-key DuckDuckGo Lite search and content-addressed fetch with automatic SHA-256 caching.
|
|
120
|
+
|
|
121
|
+
|
|
85
122
|
---
|
|
86
123
|
|
|
87
124
|
## 🏷️ Epistemic Tagging Taxonomy
|
package/bin/cli.js
CHANGED
|
@@ -25,9 +25,13 @@ Usage:
|
|
|
25
25
|
npx @heretek-ai/epistemic-swarm <command> [options]
|
|
26
26
|
|
|
27
27
|
Commands:
|
|
28
|
+
config [options] Inspect or modify swarm parameters (engine, depth, mode)
|
|
29
|
+
audit "<target>" Run dialectic codebase architectural & security audit
|
|
30
|
+
scout "<feature>" Scout open-source software, libraries & clean-room blueprints
|
|
28
31
|
run "<objective>" Run the dialectic multi-agent research swarm
|
|
29
32
|
grill Launch interactive Socratic decision tree framing
|
|
30
33
|
install Install skills & MCP servers into ~/.claude/
|
|
34
|
+
marketplace Show Claude Code marketplace catalog & install commands
|
|
31
35
|
test Run test suite for hashing, state machine & auditor
|
|
32
36
|
doctor Check environment requirements (Claude Code, Pi, OpenCode)
|
|
33
37
|
help Show this help message
|
|
@@ -40,9 +44,15 @@ Platform Extensions:
|
|
|
40
44
|
Options:
|
|
41
45
|
--mock-claude Run swarm with synthetic mock responses (zero API cost)
|
|
42
46
|
--frontier <file> Path to settled frontier.json from Socratic grilling
|
|
47
|
+
--mode <mode> Operating mode (research, audit, scout, hybrid)
|
|
48
|
+
--engine <engine> Search engine (duckduckgo, brave, firecrawl, searxng)
|
|
49
|
+
--depth <n> Max dialectic iterations (1-4)
|
|
43
50
|
--dir <path> Path to .research workspace directory (default: .research)
|
|
44
51
|
|
|
45
52
|
Examples:
|
|
53
|
+
iumbtems config --engine duckduckgo --depth 3
|
|
54
|
+
iumbtems audit "runner/ and skills/ concurrency & security"
|
|
55
|
+
iumbtems scout "Zero-dependency Raft consensus in Rust"
|
|
46
56
|
iumbtems run "Verify sub-millisecond ZK prover latency"
|
|
47
57
|
iumbtems grill --objective "Rollup architecture trade-offs"
|
|
48
58
|
iumbtems doctor
|
|
@@ -75,6 +85,31 @@ function runBash(scriptRelPath, extraArgs = []) {
|
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
switch (command) {
|
|
88
|
+
case 'config': {
|
|
89
|
+
runPython('skills/swarm_config/configure.py', args.slice(1));
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case 'audit': {
|
|
94
|
+
const targetObj = args[1] && !args[1].startsWith('--') ? args[1] : 'Full codebase architectural and security audit';
|
|
95
|
+
const restArgs = args[1] && !args[1].startsWith('--') ? args.slice(2) : args.slice(1);
|
|
96
|
+
const forwardArgs = ['--mode', 'audit', '--objective', targetObj, ...restArgs];
|
|
97
|
+
runPython('runner/research_swarm.py', forwardArgs);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
case 'scout': {
|
|
102
|
+
const objective = args[1];
|
|
103
|
+
if (!objective || objective.startsWith('--')) {
|
|
104
|
+
console.error('Error: Please provide a feature or library to scout.');
|
|
105
|
+
console.error('Example: npx @heretek-ai/epistemic-swarm scout "Zero-dependency Raft in Rust"');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
const forwardArgs = ['--mode', 'scout', '--objective', objective, ...args.slice(2)];
|
|
109
|
+
runPython('runner/research_swarm.py', forwardArgs);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
78
113
|
case 'run': {
|
|
79
114
|
const objective = args[1];
|
|
80
115
|
if (!objective || objective.startsWith('--')) {
|
|
@@ -97,6 +132,29 @@ switch (command) {
|
|
|
97
132
|
break;
|
|
98
133
|
}
|
|
99
134
|
|
|
135
|
+
case 'marketplace': {
|
|
136
|
+
const mktPath = path.join(PKG_ROOT, '.claude-plugin', 'marketplace.json');
|
|
137
|
+
if (!fs.existsSync(mktPath)) {
|
|
138
|
+
console.error('Marketplace manifest not found.');
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
const mkt = JSON.parse(fs.readFileSync(mktPath, 'utf8'));
|
|
142
|
+
console.log(`\n🏪 CLAUDE CODE MARKETPLACE: ${mkt.name.toUpperCase()}`);
|
|
143
|
+
console.log(`================================================`);
|
|
144
|
+
console.log(`Owner: ${mkt.owner ? mkt.owner.name : 'Unknown'} <${mkt.owner ? mkt.owner.email : ''}>`);
|
|
145
|
+
console.log(`Description: ${mkt.description}\n`);
|
|
146
|
+
console.log(`🚀 Add this marketplace to Claude Code:`);
|
|
147
|
+
console.log(` claude plugin marketplace add Heretek-AI/IUMBTEMS\n`);
|
|
148
|
+
console.log(`📦 Available Plugins in Marketplace:`);
|
|
149
|
+
(mkt.plugins || []).forEach((p, idx) => {
|
|
150
|
+
console.log(` ${idx + 1}. ${p.name} [${p.category || 'plugin'}]`);
|
|
151
|
+
console.log(` Description: ${p.description}`);
|
|
152
|
+
console.log(` Install: claude plugin install ${p.name}@${mkt.name}`);
|
|
153
|
+
console.log(` Configure: claude plugin configure ${p.name}@${mkt.name}\n`);
|
|
154
|
+
});
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
|
|
100
158
|
case 'test': {
|
|
101
159
|
runPython('-m', ['unittest', 'discover', '-s', 'runner/tests']);
|
|
102
160
|
break;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Intelligent MCP Server Launcher & Epistemic Fallback Proxy for IUMBTEMS.
|
|
4
|
+
Safely detects API keys and endpoints:
|
|
5
|
+
- If keys are present (via env or userConfig): launches the official MCP server.
|
|
6
|
+
- If keys are absent: smoothly provides a zero-key JSON-RPC fallback MCP server
|
|
7
|
+
backed by DuckDuckGo Lite search and content-addressed SHA256 caching.
|
|
8
|
+
Prevents startup crashes and missing environment variable errors in Claude Code.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
import os
|
|
13
|
+
import json
|
|
14
|
+
import subprocess
|
|
15
|
+
import shutil
|
|
16
|
+
from typing import Dict, Any, List
|
|
17
|
+
|
|
18
|
+
# Add parent dir to path for imports
|
|
19
|
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
20
|
+
PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
|
|
21
|
+
if PROJECT_ROOT not in sys.path:
|
|
22
|
+
sys.path.insert(0, PROJECT_ROOT)
|
|
23
|
+
|
|
24
|
+
def get_config_val(key: str, default: str = "") -> str:
|
|
25
|
+
"""Retrieve config from env, userConfig, or defaults."""
|
|
26
|
+
env_val = os.environ.get(key)
|
|
27
|
+
if env_val:
|
|
28
|
+
return env_val
|
|
29
|
+
# Also check user_config format
|
|
30
|
+
user_cfg_val = os.environ.get(f"CLAUDE_PLUGIN_OPTION_{key.upper()}")
|
|
31
|
+
if user_cfg_val:
|
|
32
|
+
return user_cfg_val
|
|
33
|
+
return default
|
|
34
|
+
|
|
35
|
+
def run_zero_key_mcp_server(service: str):
|
|
36
|
+
"""Run lightweight JSON-RPC MCP server handling search and fetch without API keys."""
|
|
37
|
+
from skills.epistemic_search.scripts.search import search_duckduckgo
|
|
38
|
+
from skills.epistemic_search.scripts.fetch import fetch_and_cache
|
|
39
|
+
|
|
40
|
+
def send_response(response: Dict[str, Any]):
|
|
41
|
+
out = json.dumps(response)
|
|
42
|
+
sys.stdout.write(f"Content-Length: {len(out)}\r\n\r\n{out}")
|
|
43
|
+
sys.stdout.flush()
|
|
44
|
+
|
|
45
|
+
def send_json(response: Dict[str, Any]):
|
|
46
|
+
# Direct newline JSON-RPC for stdio transports
|
|
47
|
+
sys.stdout.write(json.dumps(response) + "\n")
|
|
48
|
+
sys.stdout.flush()
|
|
49
|
+
|
|
50
|
+
while True:
|
|
51
|
+
try:
|
|
52
|
+
line = sys.stdin.readline()
|
|
53
|
+
if not line:
|
|
54
|
+
break
|
|
55
|
+
line = line.strip()
|
|
56
|
+
if not line:
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
# Check if line is Content-Length header or raw JSON
|
|
60
|
+
if line.startswith("Content-Length:"):
|
|
61
|
+
length = int(line.split(":")[1].strip())
|
|
62
|
+
# Read blank line
|
|
63
|
+
sys.stdin.readline()
|
|
64
|
+
body = sys.stdin.read(length)
|
|
65
|
+
req = json.loads(body)
|
|
66
|
+
use_headers = True
|
|
67
|
+
else:
|
|
68
|
+
req = json.loads(line)
|
|
69
|
+
use_headers = False
|
|
70
|
+
|
|
71
|
+
req_id = req.get("id")
|
|
72
|
+
method = req.get("method")
|
|
73
|
+
params = req.get("params", {})
|
|
74
|
+
|
|
75
|
+
if method == "initialize":
|
|
76
|
+
res = {
|
|
77
|
+
"jsonrpc": "2.0",
|
|
78
|
+
"id": req_id,
|
|
79
|
+
"result": {
|
|
80
|
+
"protocolVersion": "2024-11-05",
|
|
81
|
+
"serverInfo": {
|
|
82
|
+
"name": f"epistemic-{service}-fallback",
|
|
83
|
+
"version": "0.2.1"
|
|
84
|
+
},
|
|
85
|
+
"capabilities": {
|
|
86
|
+
"tools": {}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
elif method == "tools/list":
|
|
91
|
+
if service == "brave-search":
|
|
92
|
+
tools = [
|
|
93
|
+
{
|
|
94
|
+
"name": "brave_web_search",
|
|
95
|
+
"description": "Web search with DuckDuckGo fallback (zero API key required). Returns verifiable search results with titles, URLs, and snippets.",
|
|
96
|
+
"inputSchema": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"properties": {
|
|
99
|
+
"query": {"type": "string", "description": "The search query terms"},
|
|
100
|
+
"count": {"type": "number", "description": "Number of results (1-20)", "default": 10}
|
|
101
|
+
},
|
|
102
|
+
"required": ["query"]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
elif service == "firecrawl":
|
|
107
|
+
tools = [
|
|
108
|
+
{
|
|
109
|
+
"name": "firecrawl_scrape",
|
|
110
|
+
"description": "Scrape and extract clean markdown with automatic content-addressed SHA-256 caching into .research/sources/.",
|
|
111
|
+
"inputSchema": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"properties": {
|
|
114
|
+
"url": {"type": "string", "description": "URL to scrape and cache"}
|
|
115
|
+
},
|
|
116
|
+
"required": ["url"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
else:
|
|
121
|
+
tools = []
|
|
122
|
+
|
|
123
|
+
res = {
|
|
124
|
+
"jsonrpc": "2.0",
|
|
125
|
+
"id": req_id,
|
|
126
|
+
"result": {"tools": tools}
|
|
127
|
+
}
|
|
128
|
+
elif method == "tools/call":
|
|
129
|
+
tool_name = params.get("name")
|
|
130
|
+
args = params.get("arguments", {})
|
|
131
|
+
|
|
132
|
+
if tool_name in ("brave_web_search", "search"):
|
|
133
|
+
q = args.get("query", "")
|
|
134
|
+
count = args.get("count", 10)
|
|
135
|
+
results = search_duckduckgo(query=q, max_results=count)
|
|
136
|
+
text_out = json.dumps(results, indent=2)
|
|
137
|
+
res = {
|
|
138
|
+
"jsonrpc": "2.0",
|
|
139
|
+
"id": req_id,
|
|
140
|
+
"result": {
|
|
141
|
+
"content": [{"type": "text", "text": text_out}]
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
elif tool_name in ("firecrawl_scrape", "scrape", "fetch"):
|
|
145
|
+
target_url = args.get("url", "")
|
|
146
|
+
content = fetch_and_cache(url=target_url)
|
|
147
|
+
res = {
|
|
148
|
+
"jsonrpc": "2.0",
|
|
149
|
+
"id": req_id,
|
|
150
|
+
"result": {
|
|
151
|
+
"content": [{"type": "text", "text": content}]
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else:
|
|
155
|
+
res = {
|
|
156
|
+
"jsonrpc": "2.0",
|
|
157
|
+
"id": req_id,
|
|
158
|
+
"error": {"code": -32601, "message": f"Tool {tool_name} not found"}
|
|
159
|
+
}
|
|
160
|
+
elif method == "notifications/initialized":
|
|
161
|
+
continue
|
|
162
|
+
else:
|
|
163
|
+
res = {
|
|
164
|
+
"jsonrpc": "2.0",
|
|
165
|
+
"id": req_id,
|
|
166
|
+
"error": {"code": -32601, "message": f"Method {method} not handled"}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if use_headers:
|
|
170
|
+
send_response(res)
|
|
171
|
+
else:
|
|
172
|
+
send_json(res)
|
|
173
|
+
|
|
174
|
+
except Exception as e:
|
|
175
|
+
sys.stderr.write(f"[mcp-launcher] Error handling request: {e}\n")
|
|
176
|
+
break
|
|
177
|
+
|
|
178
|
+
def main():
|
|
179
|
+
service = sys.argv[1] if len(sys.argv) > 1 else "brave-search"
|
|
180
|
+
npx_bin = shutil.which("npx")
|
|
181
|
+
|
|
182
|
+
if service == "brave-search":
|
|
183
|
+
api_key = get_config_val("BRAVE_SEARCH_API_KEY")
|
|
184
|
+
if api_key and npx_bin:
|
|
185
|
+
os.environ["BRAVE_SEARCH_API_KEY"] = api_key
|
|
186
|
+
os.execvp(npx_bin, [npx_bin, "-y", "@modelcontextprotocol/server-brave-search"])
|
|
187
|
+
else:
|
|
188
|
+
# Fall back to zero-key search proxy
|
|
189
|
+
run_zero_key_mcp_server("brave-search")
|
|
190
|
+
|
|
191
|
+
elif service == "firecrawl":
|
|
192
|
+
api_key = get_config_val("FIRECRAWL_API_KEY")
|
|
193
|
+
api_url = get_config_val("FIRECRAWL_API_URL", "https://api.firecrawl.dev")
|
|
194
|
+
if api_key and npx_bin:
|
|
195
|
+
os.environ["FIRECRAWL_API_KEY"] = api_key
|
|
196
|
+
os.environ["FIRECRAWL_API_URL"] = api_url
|
|
197
|
+
os.execvp(npx_bin, [npx_bin, "-y", "firecrawl-mcp"])
|
|
198
|
+
else:
|
|
199
|
+
# Fall back to zero-key readability fetcher + SHA-256 hasher
|
|
200
|
+
run_zero_key_mcp_server("firecrawl")
|
|
201
|
+
|
|
202
|
+
elif service == "searxng":
|
|
203
|
+
searxng_url = get_config_val("SEARXNG_URL", "http://localhost:8080")
|
|
204
|
+
searxng_script = os.path.join(SCRIPT_DIR, "searxng_mcp.py")
|
|
205
|
+
if os.path.exists(searxng_script):
|
|
206
|
+
os.environ["SEARXNG_URL"] = searxng_url
|
|
207
|
+
os.execvp("python3", ["python3", searxng_script])
|
|
208
|
+
else:
|
|
209
|
+
run_zero_key_mcp_server("searxng")
|
|
210
|
+
else:
|
|
211
|
+
sys.stderr.write(f"Unknown service: {service}\n")
|
|
212
|
+
sys.exit(1)
|
|
213
|
+
|
|
214
|
+
if __name__ == "__main__":
|
|
215
|
+
main()
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "WebSearch",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"WebSearch intercepted by epistemic-swarm to enforce verified citation integrity. Use epistemic search (python3 ${CLAUDE_PLUGIN_ROOT}/skills/epistemic_search/scripts/search.py \\\"<query>\\\") instead.\"}}'"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"matcher": "WebFetch",
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"WebFetch intercepted by epistemic-swarm to enforce content-addressed caching. Use epistemic fetch (python3 ${CLAUDE_PLUGIN_ROOT}/skills/epistemic_search/scripts/fetch.py \\\"<url>\\\") which automatically stores documents in .research/sources/<sha256>.md for mathematical auditability.\"}}'"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|