技能运行时管理器

一个本地优先的技能运行时和可视化管理器,用于本地和开放的大型语言模型,能够从任何来源(如git、文件夹、注册表或URL)获取技能,并在运行时将正确的技能注入到三个目标中。

  • by gtm-k
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 gtm-k/skill-forge

使用说明

🔥 技能锻造

当地第一 技能运行库+可视化管理器 适用于本地和开放LLM

源 agentskills.io 网站 来自任何地方的技能(git、文件夹、注册表、URL)和技能锻造使 右一火,在运行时注入 三个目标 一个共享的核心。

来源→ 管理→ 路线→ 注入 ·确实如此 不 创作工具。


为什么

您的本地模型无法使用您的云助手可以使用的技能。agentskills.io充满了出色的技能,但它是一个运行中的模型 LM Studio, 奥拉玛, llama.cpp,或 vLLM 没有办法 找到合适的技能,并在合适的时间注入技能锻造是缺失的一层-- 完全本地化,on 127.0.0.1,每个决定都是可观察的 (“永不沉默”)。一条发动机路线;三个薄型适配器。

flowchart LR
    A["😕 You ask a local model<br/>to extract tables from a PDF"] --> B{Does it know<br/>the PDF skill?}
    B -->|"without skill-forge"| C["❌ generic answer —<br/>the skill never fires"]
    B -->|"with skill-forge"| D["✅ the PDF skill is selected<br/>+ injected at runtime"]
    style C stroke:#c0392b,stroke-width:2px
    style D stroke:#27ae60,stroke-width:2px

架构——杠杆点

一个纯粹的核心完成了这项工作: 来源→ 规范化→ 索引→ 选择→ 注入其他一切都是一个薄适配器 地方 注入到它的通道中,或者一个可选的本地守护进程来加速和观察它。

flowchart TB
    subgraph clients["foreign processes (the clients)"]
        LMS["🖥️ LM Studio<br/>GUI chats"]
        HOST["🧩 MCP host<br/>Claude Desktop · Cursor"]
        AGENT["🤖 OpenAI-compat agent<br/>Ollama · llama.cpp · vLLM"]
        BROWSER["🌐 Browser<br/>visual manager"]
    end

    subgraph daemon["@skillforge/daemon — 127.0.0.1 (optional accelerator, sole writer)"]
        direction TB
        CORE["⚙️ @skillforge/core<br/><b>source · normalize · index · SELECT · INJECT · exec</b>"]
        STORE[("🗄️ node:sqlite<br/>read-model + WAL")]
        API["REST + SSE control API · serves the UI"]
        CORE --- STORE
        CORE --- API
    end

    subgraph adapters["thin adapters (embed core; degrade with a *visible* warning if daemon is down)"]
        PLUG["@skillforge/lmstudio<br/>persisted user-turn rewrite"]
        MCP["@skillforge/mcp-server<br/>host-driven tools (stdio + HTTP)"]
        PROXY["@skillforge/proxy<br/>ephemeral /v1 system message"]
    end

    LMS --> PLUG
    HOST --> MCP
    AGENT --> PROXY
    BROWSER --> API
    PLUG -.embeds.-> CORE
    MCP -.embeds.-> CORE
    PROXY -.embeds.-> CORE
    CLI["⌨️ @skillforge/cli<br/>skill-forge add / list"] --> STORE

五个决议: ① 标题(一种技巧 解雇 在真实聊天中)首先发货,而不是代理; ② 平价是 已证实,未断言 (黄金路由门将每个适配器与核心进行比较); ③ schemaVersion 从第一天开始; ④ 守护进程是 可选加速器,从不在聊天的关键失败路径上; ⑤ 注射是 通道无关内容+每个适配器的位置 --堆芯发射 InjectionContent,每个适配器都按照其通道的持久性语义放置它。


如何选择技能——分层选择

选择只会升级到必须升级的程度,并且 使“不注射任何东西”清晰可辨 --错误的技能比没有技能更糟糕。

flowchart TD
    Q["user turn"] --> T0{"explicit?<br/>$slug or X-Skill header"}
    T0 -->|yes| FIRE["🎯 inject the named skill<br/>(Tier-0, disclosure: full)"]
    T0 -->|no| T1["Tier-1 · lexical<br/>offline BM25-style match"]
    T1 --> J1{"clears threshold<br/>+ margin over #2?"}
    J1 -->|yes| FIRE
    J1 -->|"weak / tie"| T2["Tier-2 · semantic<br/>local embeddings (nomic-embed)"]
    T2 --> AVAIL{"embeddings<br/>endpoint up?"}
    AVAIL -->|no| BANNER["⚠️ Tier-2 disabled<br/><b>visible</b> banner — never a silent downgrade"]
    AVAIL -->|yes| J2{"clears threshold?"}
    J2 -->|yes| FIRE
    J2 -->|no| NONE["∅ inject nothing<br/>θ-gauge shows why"]
    BANNER --> NONE
    style FIRE stroke:#27ae60,stroke-width:2px
    style NONE stroke:#7f8c8d,stroke-width:2px
    style BANNER stroke:#e67e22,stroke-width:2px

Spike A0根据LM Studio的实时数据进行了测量:仅词汇峰值在 77% precision@1;添加语义层达到 93% 假火≤7%。 您在路由/测试选项卡中看到的正是触发的内容。


三个目标,一个决策——注射模型

所选内容相同 InjectionContent 是 放置方式不同 每个通道,匹配每个通道的持久性语义:

flowchart LR
    SEL["core.select →<br/>InjectionContent"] --> P1 & P2 & P3
    P1["🖥️ LM Studio plugin"] --> O1["rewrites the user turn —<br/><b>persisted &amp; sticky</b> in the transcript<br/>(GUI chats)"]
    P2["🧩 MCP server"] --> O2["host-driven tools —<br/>list · load · run<br/>the <b>host</b> picks; never narrowed to one"]
    P3["🔌 OpenAI proxy"] --> O3["prepends an <b>ephemeral</b><br/>system message to a copy of<br/>messages (never persisted)"]
目标 渠道 位置 你能看到的证据
LM Studio GUI聊天 用户转重写,持久化 技能块保存在成绩单中; injectedBytes 在 inject.log.jsonl 等于着陆的字节数
主控程序 任何MCP主机 list_skills · load_skill · run_skill_script 主机菜单;无授权运行返回a 命名、审计 拒绝
代理 /v1/chat/completions 临时系统消息 X-Skill-Injected / -Disclosure / -Tier 响应标头+a select.log.jsonl 线路

安全模型——默认拒绝,每次拒绝均可观察

脚本从不静默运行。 一个经审计的执行瓶颈 每跑一次门;拒绝总是通过以下方式浮出水面 名字 并写入审计日志——绝不是无声的拒绝。

flowchart TD
    RUN["run_skill_script"] --> H["recompute the on-disk bundle hash"]
    H --> MUTE{"owner muted this<br/>skill for MCP?"}
    MUTE -->|yes| R1["⛔ refused: suppressed<br/>(non-rotatable owner mute)"]
    MUTE -->|no| GRANT{"exec granted<br/>AND hash still matches?"}
    GRANT -->|no| R2["⛔ refused: no-grant / hash-mismatch<br/>(default-deny — D2)"]
    GRANT -->|yes| INT{"interpreter resolves<br/>+ argv shape valid?"}
    INT -->|no| R3["⛔ refused: interpreter-unresolved / bad-args"]
    INT -->|yes| SPAWN["▶️ spawn (audited) — exit code + output tails"]
    R1 --> AUDIT[("📝 every outcome →<br/>exec.log.jsonl + live SSE")]
    R2 --> AUDIT
    R3 --> AUDIT
    SPAWN --> AUDIT
    style R1 stroke:#c0392b
    style R2 stroke:#c0392b
    style R3 stroke:#c0392b
    style SPAWN stroke:#27ae60,stroke-width:2px

强化亮点:阵列argv spawn (无外壳,无指令注射面);仅HTTPS克隆,带有SSRF防护;一 仅限本地入场 (非本地主机/来源→ 403);内容哈希绑定的exec允许在重新同步时自动撤销;和一个 根据技能,不可旋转的MCP运行静音 在实时和后台进程下行路径上的核心阻塞点强制执行。


单体仓库

包装 什么
@skillforge/contracts 共享类型, schemaVersion,调整了路由阈值,金色固定装置 ✅
@skillforge/core 发动机-- normalize +分层 select + inject +高管瓶颈 ✅
@skillforge/daemon 本地 node:sqlite 读取模型存储,REST+SSE打开 127.0.0.1,为UI提供服务 ✅
@skillforge/cli skill-forge add / list --来源(git/文件夹/注册表/url) ✅
@skillforge/lmstudio LM Studio插件(GUI聊天) ✅
@skillforge/mcp-server 适用于任何MCP主机的MCP技能服务器(stdio+HTTP) ✅
@skillforge/proxy OpenAI兼容的代理(Ollama·llama.cpp·vLLM·任何OpenAI兼容代理) ✅
@skillforge/ui 只读可视化管理器(技能·来源·路线/测试·活动·状态) ✅

快速入门

# 0. Zero-install: junction the workspace packages into node_modules (stand-in for pnpm install)
node scripts/link-workspace.mjs

# 1. SOURCE a skill (git URL or local folder) into your home; prints a humble capability inventory
SKILLFORGE_HOME=/tmp/sf node --experimental-strip-types packages/cli/src/bin.ts add <git-url | folder>
SKILLFORGE_HOME=/tmp/sf node --experimental-strip-types packages/cli/src/bin.ts list

# 2. BOOT the daemon + visual manager (both flags required: type-stripping + node:sqlite)
SKILLFORGE_HOME=/tmp/sf node --experimental-strip-types --experimental-sqlite packages/daemon/src/bin.ts
#   → daemon listening at http://127.0.0.1:4319/   (open it: Skills · Sources · Route/Test · Activity)

# 3. ROUTE a query headlessly (what you see here is what fires)
curl -s -X POST http://127.0.0.1:4319/route-test \
  -H 'content-type: application/json' -H 'origin: http://127.0.0.1:4319' \
  -d '{"target":"lmstudio","messages":[{"role":"user","content":"extract tables from a pdf"}]}'

三个注入目标——LM Studio插件(packages/lmstudio-plugin/RUNBOOK.md),MCP服务器(packages/mcp-server),以及代理(packages/proxy)--每个都嵌入了相同的核心。完整的端到端演练存在于私人规划文档中。


安装——连接注射靶

一次发掘你的技能(skill-forge add …,如上),然后打开您使用的任何目标。每个都嵌入了相同的核心,因此所有三个核心的路由都是相同的。

flowchart LR
    H["~/.skillforge<br/>(skills + manifest)"] --> T1 & T2 & T3
    T1["① LM Studio plugin<br/><i>one-time build + lms dev</i>"]
    T2["② MCP server<br/><i>point your host at it</i>"]
    T3["③ OpenAI proxy<br/><i>point your client's base URL at it</i>"]

① LM Studio插件(GUI聊天)

插件不能是普通包-- @lmstudio/sdk 仅存在 里面 一个内置的LM Studio插件。因此,它是由LM Studio的参考RAG-v1插件与SkillForge交换后组装而成的。整个组装过程由一个脚本完成:

# Prereq: install LM Studio's "RAG v1" plugin once — LM Studio → Discover → Plugins.
node scripts/build-lmstudio-plugin.mjs        # → builds ~/.lmstudio-skillforge-plugin
cd ~/.lmstudio-skillforge-plugin
lms dev --install --yes                       # persistent one-shot install (no watch). Or `lms dev` to iterate.

您应该看到: Successfully installed skillforge-local/skillforge-lmstudio该插件出现在LM Studio的 插件 面板——什么都没运行。(如果LM Studio未显示,请重新启动一次。)

然后在LM Studio的主页中添加一项技能(确实如此 不 继承shell的 SKILLFORGE_HOME,所以不要设置)并聊天:

SKILLFORGE_HOME= node --experimental-strip-types packages/cli/src/bin.ts add <git-url|folder>

在GUI聊天中,发送与技能匹配的消息(或明确的 $slug). 您应该看到: 技能说明 做好准备,坚持下去 在成绩单中; tail -n 1 ~/.skillforge/inject.log.jsonl 显示a injectedBytes 等于着陆的块。完整演练+天花板尺寸注意事项: packages/lmstudio-plugin/RUNBOOK.md.

② MCP服务器(克劳德桌面、光标、任何MCP主机)

将主机指向stdio服务器(您添加的技能将成为 list_skills / load_skill / run_skill_script 工具——主机选择):

// e.g. Claude Desktop / Cursor MCP config
{ "mcpServers": { "skillforge": {
    "command": "node",
    "args": ["--experimental-strip-types", "<repo>/packages/mcp-server/src/bin.ts"]
} } }

您应该看到: 主机中的三个SkillForge工具;一 run_skill_script 如果没有exec授权,则返回a 命名、审计 no-grant 拒绝(默认拒绝)。守护进程还通过HTTP在以下位置挂载MCP POST /127.0.0.1:4319/mcp.

③ OpenAI兼容代理(Ollama、llama.cpp、vLLM、任何OpenAI兼容客户端)

运行代理(将模型服务器设置为上游),并将客户端的基本URL指向它:

SKILLFORGE_PROXY_PORT=4320 node --experimental-strip-types packages/proxy/src/bin.ts
# then use base URL  http://127.0.0.1:4320/v1  in any OpenAI-compatible client

您应该看到: 聊天响应携带 x-skill-injected / x-skill-disclosure / x-skill-tier headers(临时注入在headers中是证明)。守护进程还提供 /v1/* 上 :4319.


开发(零安装)

继续运行 节点≥22.18 通过原生TypeScript类型剥离-- 无构建步骤;运行时没有依赖关系 (唯一的npm deps存在于一个隔离的、仅限开发人员的typecheck sidecar中,该sidecar由 tsc 门)。

# Full suite — --experimental-sqlite is required for the daemon (node:sqlite) suite;
# some machines OOM without --test-concurrency=2.
node --experimental-strip-types --experimental-sqlite --test-concurrency=2 --test "packages/**/test/*.ts"

# The two other local gates (mirrored in CI):
node scripts/lint-core-no-child-process.mjs   # core stays child_process-free outside the audited exec chokepoint
node scripts/typecheck.mjs                     # tsc --noEmit over src + tests via the dev-only sidecar

测试和质量门

flowchart LR
    subgraph gate["every push / PR"]
        L1["lint:<br/>core child_process-free"]
        L2["lint:<br/>no proprietary fixtures"]
        TS["tsc --noEmit<br/>(src + tests)"]
        TEST["343 tests<br/>(node:test)"]
    end
    L1 --> OK["✅ merge"]
    L2 --> OK
    TS --> OK
    TEST --> OK

路由门与 约28项真实技能+一个带标签的查询集.对等是 在三条注入路径上经过验证 针对核心——LM Studio插件(黄金平价,D5)、代理(黄金平价)和守护进程 /route-test (§8)——加上a 碰撞重启 证明(DB重建+陈旧性,第5节)和a 负设假防火天花板Lexical完全离线运行;语义层使用本地嵌入端点,如果无法到达,则自动跳过。


状态

MVP发货 --运行时+可视化管理器跨所有三个注入目标工作,由CLI、可选的本地守护进程和只读UI支持。LM Studio插件的选择/注入经过无头测试;将其连接到LM Studio的GUI是一个一次性的手动步骤(packages/lmstudio-plugin/RUNBOOK.md).


许可证

阿帕奇-2.0 --看 LICENSE.

捆绑夹具技能 packages/contracts/fixtures/skills/ 是第三方提供的内容(Anthropic 阿帕奇-2.0 技能和超能力 麻省理工学院 技能)。看 NOTICE 对于所需的归因, THIRD_PARTY_LICENSES.md 获取完整的上游许可证文本,以及 ATTRIBUTIONS.md 对于每种技能的来源图。