@heytherevibin/skillforge 0.2.1 → 0.8.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/CHANGELOG.md +43 -0
- package/README.md +89 -56
- package/RELEASING.md +1 -1
- package/SECURITY.md +2 -2
- package/STRATEGY.md +1 -3
- package/bin/cli.js +32 -138
- package/package.json +2 -2
- package/python/app/chunking.py +116 -0
- package/python/app/context_fusion.py +77 -0
- package/python/app/events_cli.py +1 -1
- package/python/app/index_cli.py +89 -0
- package/python/app/main.py +632 -229
- package/python/app/mcp_contract.py +121 -0
- package/python/app/mcp_server.py +304 -30
- package/python/app/project_index.py +600 -0
- package/python/app/redaction.py +128 -0
- package/python/app/route_cli.py +42 -19
- package/python/app/route_policies.py +133 -0
- package/python/app/routing_signals.py +95 -0
- package/python/requirements.txt +1 -4
- package/python/tests/test_chunking.py +34 -0
- package/python/tests/test_context_fusion.py +45 -0
- package/python/tests/test_mcp_contract.py +137 -0
- package/python/tests/test_project_index.py +76 -0
- package/python/tests/test_redaction.py +51 -0
- package/python/tests/test_route_policies.py +115 -0
- package/python/tests/test_routing_signals.py +77 -0
- package/python/app/auth.py +0 -63
- package/python/app/cli.py +0 -78
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
- **Smarter routing:** optional **conversation-aware** shortlist query (`SKILLFORGE_ROUTER_CONV_*`), **hybrid** retrieval (`SKILLFORGE_ROUTER_HYBRID` = `keyword` or `bm25` + `SKILLFORGE_ROUTER_HYBRID_ALPHA`), optional **Haiku rerank** (`SKILLFORGE_HAIKU_RERANK`, `SKILLFORGE_HAIKU_RERANK_MAX`, `SKILLFORGE_HAIKU_RERANK_MODEL`).
|
|
6
|
+
- **Skill cards:** YAML **`triggers`** / **`anti_triggers`** on **`SKILL.md`** are parsed and folded into summary embeddings and router prompts via **`app/routing_signals.py`** (`skill_routing_card`). Chunk RAG still scores on the **current** user message.
|
|
7
|
+
- **Dependency:** **`rank-bm25`** in `python/requirements.txt` (BM25 hybrid; optional at runtime if you use `keyword` only).
|
|
8
|
+
|
|
9
|
+
## 0.7.1
|
|
10
|
+
|
|
11
|
+
- **MCP:** **`search_skills`** (embedding shortlist + snippets), **`explain_route`** (routing diagnostics, no DB writes), **`get_skill`** (fetch one **`SKILL.md`** by name).
|
|
12
|
+
- **Route policies:** optional **`SKILLFORGE_ROUTE_POLICIES`**, **`SKILLFORGE_ROUTE_POLICIES_FILE`**, or **`project_root`/** `.skillforge/policies.json` / **`skillforge-policies.json`** — regex rules append **`include`** skills after the router (capped by **`SKILLFORGE_MAX_ACTIVE`**). Audit stored on route events under **`policy`**.
|
|
13
|
+
|
|
14
|
+
## 0.7.0
|
|
15
|
+
|
|
16
|
+
- **Breaking:** Removed the optional **HTTP API** (`skillforge start`), **`skillforge chat`** harness, and **`skillforge auth`** (bearer tokens were only used by HTTP). MCP (`skillforge mcp`), **`skillforge route`**, **`skillforge events`**, and **`skillforge index`** are unchanged.
|
|
17
|
+
- **Migration:** The CLI deletes a leftover **`~/.skillforge/auth.json`** on **every** invocation (including **`skillforge --help`**), once the file is gone the message stops.
|
|
18
|
+
- Dropped **FastAPI**, **uvicorn**, and direct **pydantic** / **httpx** dependencies from `python/requirements.txt` (routing still uses libraries that may bundle their own deps).
|
|
19
|
+
|
|
20
|
+
## 0.6.0
|
|
21
|
+
|
|
22
|
+
- **Phase 4 context safety (MCP meta 1.4)**: Default **secret / credential pattern redaction** and optional **home-directory stripping** on injected chunk text, relative **`path`** fields, stored route **`prompt`** snippet, **`reasoning`**, and **`orchestrator_db`** in **`_meta`**. Disable with **`SKILLFORGE_REDACT_CONTEXT=0`**; path scrub with **`SKILLFORGE_REDACT_HOME_IN_PATHS=0`**. New **[`app/redaction.py`](python/app/redaction.py)**; route events include **`context_redaction`** hit counts.
|
|
23
|
+
|
|
24
|
+
## 0.5.0
|
|
25
|
+
|
|
26
|
+
- **Phase 3 context fusion (MCP meta 1.3)**: When **`include_project_rag`** is on and the project index is non-empty, skill + project chunk **pools** are merged with **greedy MMR** under a single **`SKILLFORGE_CONTEXT_BUDGET_CHARS`** (default: route max + project RAG max). Disable with **`SKILLFORGE_CONTEXT_FUSION=0`** to keep append-only behavior.
|
|
27
|
+
- **Telemetry**: route events and **`_meta.fusion`** include MMR trace; each context item may carry **`mmr_rank`**, **`mmr_score`**, **`retrieval_relevance`**, **`max_sim_to_prior`**.
|
|
28
|
+
- New **[`app/context_fusion.py`](python/app/context_fusion.py)**; **`load_project_fusion_pool`** in **`project_index`**.
|
|
29
|
+
|
|
30
|
+
## 0.4.0
|
|
31
|
+
|
|
32
|
+
- **Phase 2 project RAG (MCP 1.2)**: **`skillforge index --project-root=…`** walks the repo (bounded file sizes, ignore dirs), chunks text files, and stores **`project_chunks`** + embeddings in **`<project>/.skillforge/orchestrator.db`** (same DB as sessions/weights).
|
|
33
|
+
- **MCP / CLI / HTTP**: optional **`include_project_rag`** (MCP + **`skillforge route --include-project-rag`**) appends top matching file chunks under **`SKILLFORGE_PROJECT_RAG_MAX_CHARS`**. **`_meta`**: schema **1.2**; **`sources`** may include **`kind: file`**; **`budget.chars_project_chunks`** / **`chars_context_items_total`**.
|
|
34
|
+
|
|
35
|
+
## 0.3.0
|
|
36
|
+
|
|
37
|
+
- **Phase 1 skill RAG (MCP 1.1)**: Default **`SKILLFORGE_CONTEXT_MODE=chunks`** — line-bounded chunks from each picked **`SKILL.md`** body, scored by query similarity, injected up to **`SKILLFORGE_ROUTE_MAX_CHARS`**. Set **`full_body`** for legacy whole-document injection per skill.
|
|
38
|
+
- **`_meta`**: schema **1.1**; **`sources`** lists chunk-level rows with **`line_start` / `line_end`** and **`score`**; **`context_items_count`**.
|
|
39
|
+
- New **[`app/chunking.py`](python/app/chunking.py)**; **`Router.build_context_items`**, **`format_context_items_markdown`**.
|
|
40
|
+
|
|
41
|
+
## 0.2.2
|
|
42
|
+
|
|
43
|
+
- **MCP Phase 0 contract**: **`route_skills`** success responses include versioned **`_meta`** (`schema_version` **1.0**, **`sources`**, **`budget`**, **`candidates_preview`**). Empty prompt returns **`isError`** + **`_meta.error`**. Shared builder in **`app.mcp_contract`**; **`skillforge route --json-meta`** matches.
|
|
44
|
+
- **Docs**: README “MCP response contract” section.
|
|
45
|
+
|
|
3
46
|
## 0.2.1
|
|
4
47
|
|
|
5
48
|
- Same code as **0.2.0**. **npm never allows reusing a version** after it has been published once—even if you **unpublish** it and only **0.1.0** remains visible. The registry still blocks **`0.2.0`**; ship **`0.2.1`** (or higher) instead.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
**Primary interface:** **stdio MCP** (`skillforge mcp`) — add it to Claude Desktop, Cursor, or Claude Code.
|
|
12
12
|
|
|
13
|
-
**
|
|
13
|
+
**Observability:** run **`skillforge events --watch`** in a terminal (top skills, active sessions, and live **route** / **feedback** lines from SQLite).
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -23,11 +23,10 @@
|
|
|
23
23
|
- [Usage](#usage)
|
|
24
24
|
- [Run modes](#run-modes)
|
|
25
25
|
- [Model Context Protocol (MCP)](#model-context-protocol-mcp)
|
|
26
|
-
|
|
26
|
+
- [MCP response contract](#mcp-response-contract)
|
|
27
27
|
- [Skills and packs](#skills-and-packs)
|
|
28
28
|
- [Routing pipeline](#routing-pipeline)
|
|
29
29
|
- [Configuration](#configuration)
|
|
30
|
-
- [HTTP API](#http-api)
|
|
31
30
|
- [Local data and operations](#local-data-and-operations)
|
|
32
31
|
- [Security considerations](#security-considerations)
|
|
33
32
|
- [Contributing and governance](#contributing-and-governance)
|
|
@@ -47,7 +46,7 @@
|
|
|
47
46
|
| **Observability** | **`skillforge events`**: snapshots of **usage** + **active sessions**, **`--watch`** for realtime; **`--verbose`** for route detail. No browser UI. |
|
|
48
47
|
| **Project bootstrap** | MCP tools **`materialize_project`** and **`skillforge_bootstrap`** write `.cursor/rules`, **`docs/SKILLFORGE-PRD.md`**, and a **`CLAUDE.md`** section (map **`/skillforge`** in rules to MCP tools). |
|
|
49
48
|
| **Extensibility** | Custom skills, git-based **packs**, and overrides under a single user config directory. |
|
|
50
|
-
| **Deployment flexibility** | **MCP stdio**
|
|
49
|
+
| **Deployment flexibility** | **MCP stdio** as the default integration; **CLI** helpers (`route`, `events`, `index`). |
|
|
51
50
|
|
|
52
51
|
Bundled content includes **200+** curated skills (coding, security, research, frontend/backend patterns, and more). Exact counts are validated in CI.
|
|
53
52
|
|
|
@@ -58,8 +57,8 @@ Bundled content includes **200+** curated skills (coding, security, research, fr
|
|
|
58
57
|
| Dependency | Version | Notes |
|
|
59
58
|
|------------|---------|--------|
|
|
60
59
|
| **Node.js** | **>= 18** | Required for the CLI bootstrapper. Continuous integration runs on **Node 22**. |
|
|
61
|
-
| **Python** | **>= 3.10** | Used on the host PATH for embeddings and the
|
|
62
|
-
| **Anthropic API** | — | **`ANTHROPIC_API_KEY`**
|
|
60
|
+
| **Python** | **>= 3.10** | Used on the host PATH for embeddings and routing (via the CLI-spawned **venv**). |
|
|
61
|
+
| **Anthropic API** | — | **`ANTHROPIC_API_KEY`** enables the **full** (Haiku) router when you want it. **MCP** can run **without** it using **embedding-only** routing (default when the key is omitted; see [MCP](#model-context-protocol-mcp)). |
|
|
63
62
|
|
|
64
63
|
**First run:** The CLI creates **`~/.skillforge/`**, a dedicated **Python venv**, installs Python dependencies, and caches the default embedding model (typically on the order of one to two minutes once; subsequent starts are fast).
|
|
65
64
|
|
|
@@ -73,12 +72,6 @@ npx --yes @heytherevibin/skillforge --help
|
|
|
73
72
|
|
|
74
73
|
Add Skillforge to your MCP config (see [MCP](#model-context-protocol-mcp)). No `ANTHROPIC_API_KEY` is required for **embedding-only** routing.
|
|
75
74
|
|
|
76
|
-
Optional HTTP API (e.g. for `skillforge chat`): set **`ANTHROPIC_API_KEY`**, then:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
skillforge start
|
|
80
|
-
```
|
|
81
|
-
|
|
82
75
|
Live log (usage + routes): **`skillforge events --watch`**.
|
|
83
76
|
|
|
84
77
|
---
|
|
@@ -111,11 +104,9 @@ Source and issues: [github.com/heytherevibin/skillforge](https://github.com/heyt
|
|
|
111
104
|
|---------|---------|
|
|
112
105
|
| `skillforge --help` | Recommended first step; **MCP** is the main integration. |
|
|
113
106
|
| `skillforge mcp` | **stdio** MCP server (Claude, Cursor, …). |
|
|
114
|
-
| `skillforge start [--port=8000]` | Optional **HTTP API** (no HTML or WebSocket UI). |
|
|
115
107
|
| `skillforge events [--watch]` | **Terminal** log: usage snapshot + routes; see **`skillforge events --help`**. |
|
|
116
108
|
| `skillforge route […]` | **Terminal** routing — same pipeline as MCP **`route_skills`** (loads embed model); see **`skillforge route --help`**. |
|
|
117
109
|
| `skillforge mcp config [--local] [--with-anthropic]` | **stdout**: JSON snippet for **`mcp.json`** (merge manually). |
|
|
118
|
-
| `skillforge chat` | Dev harness: HTTP client to **`POST /chat`** (needs **`start`** + API key). |
|
|
119
110
|
|
|
120
111
|
### Model Context Protocol (MCP)
|
|
121
112
|
|
|
@@ -163,29 +154,34 @@ With **Haiku** routing (uses your Anthropic key in the MCP process):
|
|
|
163
154
|
|
|
164
155
|
| Tool | Purpose |
|
|
165
156
|
|------|---------|
|
|
166
|
-
| `route_skills` | Returns routed **`SKILL.md`**
|
|
157
|
+
| `route_skills` | Returns routed **`SKILL.md`** context (chunks or full body). Pass **`project_root`** for per-repo SQLite under **`.skillforge/orchestrator.db`**. Optional **`include_project_rag`** (after **`skillforge index --project-root=…`**), **`session_id`**, **`user_id`** / **`SKILLFORGE_MCP_USER_ID`**, or env **`SKILLFORGE_PROJECT_ROOT`**. Route **`event.policy`** in SQLite logs policy merge audit when rules apply. |
|
|
158
|
+
| `search_skills` | Embedding-only shortlist for a **`query`** (scores + description snippets); does not run Haiku or mutate sessions. Optional **`limit`** (max 50). |
|
|
159
|
+
| `explain_route` | Same routing signal as **`route_skills`** without writing SQLite (**`picked_before_policy`**, **`picked_after_policy`**, shortlist facets, policy audit). For debugging. |
|
|
160
|
+
| `get_skill` | Fetch one catalog skill by **`skill_name`**; **`format`**: **`full`** or **`summary`**; optional **`max_chars`**. |
|
|
167
161
|
| `list_skills` | Catalog overview; optional **`user_id`** scopes usage stats. |
|
|
168
|
-
| `skill_feedback` | Feedback for the learning loop; optional **`user_id`**, **`session_id`** (
|
|
162
|
+
| `skill_feedback` | Feedback for the learning loop; optional **`user_id`**, **`session_id`** (stored with events). |
|
|
169
163
|
| `skill_referenced` | Mark a routed skill as **used** in the reply (increments **`referenced`** + weight; optional **`user_id`**). |
|
|
170
164
|
| `disable_skill` | Toggle skills; optional **`user_id`**. |
|
|
171
165
|
| `materialize_project` | Writes **`.cursor/rules/skillforge.mdc`**, **`docs/SKILLFORGE-PRD.md`**, updates **`CLAUDE.md`** (Skillforge block). Args: **`project_root`**, **`skill_names`** from **`route_skills`**. |
|
|
172
166
|
| `skillforge_bootstrap` | **`route_skills`** + **`materialize_project`** in one call (needs **`project_root`**). |
|
|
173
167
|
|
|
174
|
-
|
|
168
|
+
### MCP response contract
|
|
175
169
|
|
|
176
|
-
|
|
170
|
+
Structured diagnostics for tool **`route_skills`** live in **`result._meta`** (hosts may ignore or log them):
|
|
177
171
|
|
|
178
|
-
|
|
172
|
+
- **`schema_version`**: **`1.4`** — same as **1.3** plus optional **`context_redaction`** (`enabled`, `secret_hits`, `path_hits`) on **`route_skills`** success.
|
|
173
|
+
- **`sources`**: citations; each item has **`kind`** (`skill` or **`file`**), **`ref`**, **`line_start`** / **`line_end`**, **`score`**, optional **`mmr_rank`** after fusion.
|
|
174
|
+
- **`fusion`**: present when MMR fusion ran (**`enabled`: true**): **`lambda`**, **`budget_chars`**, **`pool_skill`**, **`pool_project`**, **`mmr_trace`**, …
|
|
175
|
+
- **`context_redaction`**: optional; when scrubbing is enabled, reports **`enabled`**, **`secret_hits`**, **`path_hits`** for exported context.
|
|
176
|
+
- **`budget`**: **`chars_skill_bodies`**, **`chars_project_chunks`**, **`chars_context_items_total`**, **`chars_response_total`**, **`est_tokens_approx`** (rough `chars/4`).
|
|
177
|
+
- **`candidates_preview`**: up to 15 shortlist entries **`{ name, score }`** for debugging.
|
|
178
|
+
- **`picked`**, **`reasoning`**, **`session_id`**, **`user_id`**, **`rerouted`**, **`change_pct`**, **`route_ms`**, **`orchestrator_db`**.
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
On validation errors (e.g. empty **`prompt`**), the tool returns **`isError`: true** and **`_meta.error`** (e.g. **`empty_prompt`**), still with **`schema_version`** and **`sources`: `[]`**.
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
skillforge auth add <user-id>
|
|
184
|
-
skillforge auth list
|
|
185
|
-
skillforge auth remove <user-id>
|
|
186
|
-
```
|
|
182
|
+
`/skillforge` is not registered by npm installs; add a **Cursor rule** or **CLAUDE.md** instruction so the agent calls these tools when the user asks.
|
|
187
183
|
|
|
188
|
-
|
|
184
|
+
Route events go to **`~/.skillforge/data/orchestrator.db`** (or per-repo **`.skillforge/orchestrator.db`** when **`project_root`** is set); use **`skillforge events`** to inspect them.
|
|
189
185
|
|
|
190
186
|
---
|
|
191
187
|
|
|
@@ -203,10 +199,14 @@ skillforge skills list
|
|
|
203
199
|
---
|
|
204
200
|
name: my-skill
|
|
205
201
|
description: Clear trigger conditions—used by the router.
|
|
202
|
+
triggers: When the user asks about X or mentions Y.
|
|
203
|
+
anti_triggers: Not for production deploy checks.
|
|
206
204
|
---
|
|
207
205
|
# My Skill
|
|
208
206
|
```
|
|
209
207
|
|
|
208
|
+
Optional **`triggers`** / **`anti_triggers`** strings are embedded with the summary card and shown to the Haiku router (they do not change chunk RAG, which still keys off the current user message).
|
|
209
|
+
|
|
210
210
|
Register with `skillforge skills add ./my-skill` or copy the folder to **`~/.skillforge/skills/`**.
|
|
211
211
|
|
|
212
212
|
**Skill packs** are git repositories with a root **`skillforge.json`** manifest listing skill folder names. Install:
|
|
@@ -224,16 +224,38 @@ skillforge pack remove <name>
|
|
|
224
224
|
## Routing pipeline
|
|
225
225
|
|
|
226
226
|
```
|
|
227
|
-
User prompt
|
|
228
|
-
→ Local embeddings (sentence-transformers)
|
|
229
|
-
→ Cosine similarity + per-user weights
|
|
227
|
+
User prompt (+ optional recent conversation for the shortlist query)
|
|
228
|
+
→ Local embeddings (sentence-transformers) on skill **cards** (title, description, optional triggers)
|
|
229
|
+
→ Cosine similarity ± hybrid keyword/BM25 fusion + per-user weights
|
|
230
230
|
→ Top-K candidates
|
|
231
|
+
→ Optional Haiku **rerank** on the shortlist (`SKILLFORGE_HAIKU_RERANK`)
|
|
231
232
|
→ Router model (Haiku) selects final active skills — *or* embedding-only mode takes top-N from candidates
|
|
232
233
|
→ Skill bodies injected; response model answers (e.g. Opus)
|
|
233
234
|
→ Usage signals update weights (optional)
|
|
234
235
|
```
|
|
235
236
|
|
|
236
|
-
Re-route: when overlap between successive active sets falls below a configurable threshold, the pipeline selects a new set for the next turn. Events are stored in SQLite; stream them with **`skillforge events --watch
|
|
237
|
+
Re-route: when overlap between successive active sets falls below a configurable threshold, the pipeline selects a new set for the next turn. Events are stored in SQLite; stream them with **`skillforge events --watch`**.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Route policies (optional)
|
|
242
|
+
|
|
243
|
+
Rules use **`if_text_matches`** as a Python **`re.search`** pattern (with **`re.DOTALL`**) on the user **`prompt`**. **`include`** is a skill name or list of names. Matched skills are **appended** after Haiku/embedding picks until **`SKILLFORGE_MAX_ACTIVE`**.
|
|
244
|
+
|
|
245
|
+
**Load order:** env **`SKILLFORGE_ROUTE_POLICIES`** (inline JSON) → **`SKILLFORGE_ROUTE_POLICIES_FILE`** → **`<project_root>/.skillforge/policies.json`** → **`<project_root>/skillforge-policies.json`**.
|
|
246
|
+
|
|
247
|
+
Example **`.skillforge/policies.json`**:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"rules": [
|
|
252
|
+
{
|
|
253
|
+
"if_text_matches": "(?i)(auth|oauth|jwt|password|login)",
|
|
254
|
+
"include": ["security-review"]
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
```
|
|
237
259
|
|
|
238
260
|
---
|
|
239
261
|
|
|
@@ -243,36 +265,46 @@ Environment variables (see also inline help and server defaults):
|
|
|
243
265
|
|
|
244
266
|
| Variable | Default | Role |
|
|
245
267
|
|----------|---------|------|
|
|
246
|
-
| `ANTHROPIC_API_KEY` | — | **
|
|
247
|
-
| `SKILLFORGE_ROUTER_MODE` | *(auto)* | `full` = always use Haiku for final pick (
|
|
248
|
-
| `SKILLFORGE_PORT` | `8000` | HTTP listen port. |
|
|
268
|
+
| `ANTHROPIC_API_KEY` | — | **Optional** for MCP: omit for embedding-only routing (default when unset); set for **full** (Haiku) routing. |
|
|
269
|
+
| `SKILLFORGE_ROUTER_MODE` | *(auto)* | `full` = always use Haiku for final pick (requires key). `embedding` = skip Haiku; top `SKILLFORGE_MAX_ACTIVE` from shortlist. Unset = **auto**: embedding-only when `ANTHROPIC_API_KEY` is absent, else full. |
|
|
249
270
|
| `SKILLFORGE_EMBED_MODEL` | `all-MiniLM-L6-v2` | Embedding model id. |
|
|
250
|
-
| `SKILLFORGE_ROUTER_MODEL` | `claude-haiku-4-5-20251001` | Routing model. |
|
|
251
|
-
| `SKILLFORGE_ANSWER_MODEL` | `claude-opus-4-7` | Main response model. |
|
|
271
|
+
| `SKILLFORGE_ROUTER_MODEL` | `claude-haiku-4-5-20251001` | Routing model (Haiku). |
|
|
252
272
|
| `SKILLFORGE_TOP_K` | `15` | Embedding shortlist size. |
|
|
253
273
|
| `SKILLFORGE_MAX_ACTIVE` | `7` | Maximum skills injected per turn. |
|
|
254
274
|
| `SKILLFORGE_REROUTE_THRESHOLD` | `0.4` | Re-route sensitivity (Jaccard distance). |
|
|
255
|
-
| `
|
|
275
|
+
| `SKILLFORGE_ROUTER_CONV_MAX_TURNS` | `0` | Include this many recent **conversation** messages in the **embedding shortlist** query (`0` = current user message only, legacy). |
|
|
276
|
+
| `SKILLFORGE_ROUTER_CONV_MSG_CHARS` | `320` | Max characters per message when building the shortlist query. |
|
|
277
|
+
| `SKILLFORGE_ROUTER_HYBRID` | `off` | `off` = dense cosine only. `keyword` = fuse with token overlap on skill cards. `bm25` = fuse with **BM25** (requires **`rank-bm25`**; falls back to keyword if missing). |
|
|
278
|
+
| `SKILLFORGE_ROUTER_HYBRID_ALPHA` | `0.72` | Hybrid weight on **dense** similarity (`1` = dense only; `0` = sparse only). |
|
|
279
|
+
| `SKILLFORGE_ROUTER_PROMPT_HISTORY_MSGS` | `8` | Max conversation turns sent to the **Haiku** router and reranker. |
|
|
280
|
+
| `SKILLFORGE_ROUTER_PROMPT_HISTORY_CHARS` | `360` | Max characters per turn in router / rerank prompts. |
|
|
281
|
+
| `SKILLFORGE_ROUTER_CATALOG_PREVIEW_CHARS` | `280` | Max characters of each skill **routing card** in the Haiku pick prompt. |
|
|
282
|
+
| `SKILLFORGE_HAIKU_RERANK` | `0` | Set **`1`** / **`true`** to rerank the Top-K shortlist with Haiku before the final pick (extra API call). |
|
|
283
|
+
| `SKILLFORGE_HAIKU_RERANK_MAX` | `SKILLFORGE_TOP_K` | Max candidates passed to the reranker. |
|
|
284
|
+
| `SKILLFORGE_HAIKU_RERANK_MODEL` | *(same as router)* | Model id for reranking when set; otherwise **`SKILLFORGE_ROUTER_MODEL`**. |
|
|
285
|
+
| `SKILLFORGE_CONTEXT_MODE` | `chunks` | `chunks` = embed **line-bounded chunks** from each picked skill body (RAG) up to **`SKILLFORGE_ROUTE_MAX_CHARS`**. `full_body` = inject entire **SKILL.md** per pick (legacy). |
|
|
286
|
+
| `SKILLFORGE_CHUNK_MAX_CHARS` | `1200` | Max characters per chunk (before overlap split). |
|
|
287
|
+
| `SKILLFORGE_CHUNK_OVERLAP` | `200` | Character overlap when hard-splitting an oversized section. |
|
|
288
|
+
| `SKILLFORGE_ROUTE_MAX_CHARS` | `60000` | Skill chunk char cap when **`SKILLFORGE_CONTEXT_FUSION`** is off (append path); also part of default unified budget sum when fusion is on. |
|
|
289
|
+
| `SKILLFORGE_PROJECT_RAG_MAX_CHARS` | `24000` | Project chunk char cap when fusion is off (append path); part of default unified budget when fusion is on. |
|
|
290
|
+
| `SKILLFORGE_CONTEXT_BUDGET_CHARS` | *(route + project RAG defaults)* | Single cap for **MMR-fused** skill + project context. |
|
|
291
|
+
| `SKILLFORGE_CONTEXT_FUSION` | `1` | **`0`** / **`false`**: disable MMR fusion; append project chunks after skills. |
|
|
292
|
+
| `SKILLFORGE_CONTEXT_MMR_LAMBDA` | `0.7` | MMR tradeoff: higher ⇒ query relevance; lower ⇒ diversity vs. already-selected chunks. |
|
|
293
|
+
| `SKILLFORGE_FUSION_POOL_SKILL` | `96` | Max skill chunks in the fusion candidate pool. |
|
|
294
|
+
| `SKILLFORGE_FUSION_POOL_PROJECT` | `96` | Max project chunks in the fusion candidate pool. |
|
|
295
|
+
| `SKILLFORGE_FUSION_FULL_BODY_PREVIEW_CHARS` | `4000` | **`SKILL.md`** prefix length for embedding full-body / fallback fusion rows. |
|
|
296
|
+
| `SKILLFORGE_PROJECT_RAG_MAX_CHUNKS` | `20000` | Max **project_chunks** rows loaded for one retrieval. |
|
|
297
|
+
| `SKILLFORGE_INDEX_MAX_FILE_BYTES` | `524288` | Skip indexing files larger than this (bytes). |
|
|
298
|
+
| `SKILLFORGE_INDEX_IGNORE_DIRS` | `""` | Extra comma-separated directory **basename** ignores (e.g. `out,tmp`). |
|
|
299
|
+
| `SKILLFORGE_REDACT_CONTEXT` | `1` | When **`1`** (default), scrub common secret shapes and (with home path scrub) exported context before MCP/CLI output and route events. |
|
|
300
|
+
| `SKILLFORGE_REDACT_HOME_IN_PATHS` | `1` | Replace resolved home-directory prefixes in chunk paths / DB path hints with **`[HOME]`**. |
|
|
301
|
+
| `SKILLFORGE_MCP_USER_ID` | `""` | Default logical **user id** for MCP tool calls when arguments omit `user_id` (weights, sessions, events). |
|
|
256
302
|
| `SKILLFORGE_PROJECT_ROOT` | `""` | Default workspace root when MCP **`project_root`** is omitted: events/weights/sessions live in **`<root>/.skillforge/orchestrator.db`**. Prefer passing **`project_root`** on each tool call from the host. |
|
|
257
303
|
| `SKILLFORGE_SKILL_HOT_RELOAD` | `1` | When **`0`** / **`false`**, disable **SKILL.md** hot-reload; restart the MCP process to refresh the catalog. |
|
|
258
304
|
| `SKILLFORGE_WATCH_SKILLS_INTERVAL` | `30` | Seconds between background catalog checks when hot reload is on. **`0`**: no background polling and no MCP **`tools.listChanged`**; **`tools/list`** and **`tools/call`** still reload when files change. |
|
|
259
305
|
| `SKILLFORGE_MCP_LIST_CHANGED` | `1` | When **`0`** / **`false`**, never emit **`notifications/tools/list_changed`** (and **`listChanged`** is not advertised), even if a background interval is set. |
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
## HTTP API
|
|
264
|
-
|
|
265
|
-
| Method | Path | Description |
|
|
266
|
-
|--------|------|-------------|
|
|
267
|
-
| `POST` | `/chat` | Primary chat; SSE stream. |
|
|
268
|
-
| `POST` | `/feedback` | Skill feedback for learning. |
|
|
269
|
-
| `POST` | `/skills/disable` | Enable/disable a skill flag. |
|
|
270
|
-
| `GET` | `/skills` | Catalog with stats and weights. |
|
|
271
|
-
| `GET` | `/events` | Recent routing events (`?limit=`). |
|
|
272
|
-
| `GET` | `/` | JSON service hint (use **`skillforge events --watch`** for a live terminal log). |
|
|
273
|
-
| `GET` | `/healthz` | Health metadata (`skills_loaded`, **`live_log`** hint). |
|
|
274
|
-
|
|
275
|
-
Authenticated mode applies **`Bearer`** tokens as described above. Do not expose unauthenticated instances beyond trusted networks.
|
|
306
|
+
| `SKILLFORGE_ROUTE_POLICIES` | `""` | Optional inline JSON policies document (see [Route policies](#route-policies-optional)). |
|
|
307
|
+
| `SKILLFORGE_ROUTE_POLICIES_FILE` | `""` | Path to a policies JSON file. |
|
|
276
308
|
|
|
277
309
|
---
|
|
278
310
|
|
|
@@ -282,7 +314,8 @@ Optional **per-project** state (when **`project_root`** or **`SKILLFORGE_PROJECT
|
|
|
282
314
|
|
|
283
315
|
```
|
|
284
316
|
<workspace>/.skillforge/
|
|
285
|
-
├── orchestrator.db # SQLite
|
|
317
|
+
├── orchestrator.db # SQLite: sessions, weights, events, **project_chunks** (after `skillforge index`)
|
|
318
|
+
├── policies.json # Optional route policies (see README)
|
|
286
319
|
└── last_route.json # Last route_skills snapshot (after a routed call)
|
|
287
320
|
```
|
|
288
321
|
|
|
@@ -295,12 +328,12 @@ Global default when no project root:
|
|
|
295
328
|
├── skills/ # User-added skills
|
|
296
329
|
├── packs/<hash>/ # Cloned pack repositories
|
|
297
330
|
├── packs.json # Pack registry
|
|
298
|
-
└── auth.json # Tokens (POSIX mode 0600 when used)
|
|
299
331
|
```
|
|
300
332
|
|
|
301
333
|
| Command | Effect |
|
|
302
334
|
|---------|--------|
|
|
303
335
|
| `skillforge events` | Prints a **usage** snapshot and recent **`route`** / **`feedback`** rows; **`--watch`**, **`--project-root`** (per-repo DB), **`--user`**, **`--verbose`** (see **`--help`**). |
|
|
336
|
+
| `skillforge index` | Chunk/embed text files under **`--project-root`** into **`project_chunks`**. **`--reset`**, **`--stats-only`**, **`--quiet`** (see **`--help`**). |
|
|
304
337
|
| `skillforge reset` | Clears learning state and event history in the database. |
|
|
305
338
|
| `skillforge install` | Re-runs bootstrap (venv and dependencies). |
|
|
306
339
|
| `rm -rf ~/.skillforge` | Full removal of local state and venv. |
|
|
@@ -309,8 +342,8 @@ Global default when no project root:
|
|
|
309
342
|
|
|
310
343
|
## Security considerations
|
|
311
344
|
|
|
312
|
-
-
|
|
313
|
-
-
|
|
345
|
+
- **Redaction is best-effort regex scrubbing**, not a guarantee. Do not paste production secrets into prompts; treat routed context like **untrusted text** until reviewed.
|
|
346
|
+
- Treat **`ANTHROPIC_API_KEY`** as a **secret** when you set it (e.g. for Haiku routing in MCP). Prefer environment injection or secret stores, not committed files.
|
|
314
347
|
- Vulnerability disclosure: see **[SECURITY.md](SECURITY.md)**.
|
|
315
348
|
|
|
316
349
|
---
|
package/RELEASING.md
CHANGED
|
@@ -77,7 +77,7 @@ npm test
|
|
|
77
77
|
Python (syntax only):
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
for f in python/app/main.py python/app/
|
|
80
|
+
for f in python/app/main.py python/app/mcp_server.py python/app/events_cli.py python/app/materialize.py python/app/db_paths.py python/app/route_cli.py python/app/mcp_contract.py python/app/chunking.py python/app/project_index.py python/app/index_cli.py python/app/context_fusion.py python/app/redaction.py python/app/route_policies.py python/app/routing_signals.py; do python3 -m py_compile "$f"; done
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
## Troubleshooting: `EOTP` / one-time password in CI
|
package/SECURITY.md
CHANGED
|
@@ -26,6 +26,6 @@ We aim to acknowledge valid reports within a few business days.
|
|
|
26
26
|
- Keep **2FA** enabled on the npm account that owns the `@heytherevibin` scope.
|
|
27
27
|
- Prefer pinning action versions or reviewing Dependabot PRs before merge.
|
|
28
28
|
|
|
29
|
-
## Runtime
|
|
29
|
+
## Runtime security
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Skillforge’s published surface is **local**: **stdio MCP** and **CLI** commands. Keep your **MCP host** and **`ANTHROPIC_API_KEY`** (if used) within a trusted environment. Do not commit secrets.
|
package/STRATEGY.md
CHANGED
|
@@ -7,8 +7,7 @@ Skillforge is an **npm-packaged skill orchestrator**: it routes tasks to a small
|
|
|
7
7
|
## Surfaces (today)
|
|
8
8
|
|
|
9
9
|
- **MCP** (`skillforge mcp`): primary — `route_skills`, `list_skills`, feedback tools, `materialize_project`, `skillforge_bootstrap`.
|
|
10
|
-
- **Terminal**: `skillforge events --watch` with optional **`--project-root
|
|
11
|
-
- **HTTP** (`skillforge start`): optional; still uses the global DB in **app_state** (not per-request project root unless extended later).
|
|
10
|
+
- **Terminal**: `skillforge events --watch` with optional **`--project-root`**; `skillforge route`, `skillforge index`.
|
|
12
11
|
|
|
13
12
|
## Cursor reality
|
|
14
13
|
|
|
@@ -17,7 +16,6 @@ Native **`/skillforge`** in editor chat is **not** registered by this npm packag
|
|
|
17
16
|
## Near-term backlog
|
|
18
17
|
|
|
19
18
|
- Shared **`orchestrate()`** API for MCP + CLI parity.
|
|
20
|
-
- HTTP: optional **`project_root`** header or body for `/chat` if needed.
|
|
21
19
|
- Tests: MCP handshake + `resolve_orchestrator_db` behavior.
|
|
22
20
|
|
|
23
21
|
## Non-goals (v1)
|