@rhize/skill-forge 0.4.0 → 0.6.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.
@@ -1,9 +1,11 @@
1
1
  # Skill Ingestion Pass
2
2
 
3
- You are running the deep decide/absorb pass on a skill that has just cleared the
4
- `skill-forge` quarantine → profile → safety scan → overlap-analysis gate. The gate already
5
- answered "is this safe to install?" — your job is the harder question: "given everything
6
- already in this skill set, what should actually be *done* with it?"
3
+ You are running the deep decide/absorb pass on a candidate — a skill, or (since
4
+ skill-forge v0.6) an MCP server — that has just cleared the `skill-forge` quarantine →
5
+ profile → safety scan → overlap-analysis gate. The gate already answered "is this safe to
6
+ install?" — your job is the harder question: "given everything already configured, what
7
+ should actually be *done* with it?" §1 below tells you which branch to follow depending on
8
+ the candidate's type.
7
9
 
8
10
  You may be any coding agent (Claude Code, Codex CLI, Cursor, Windsurf, OpenCode, Gemini
9
11
  CLI, or another). Nothing below assumes a specific one. Use whatever file-reading,
@@ -29,7 +31,7 @@ is a JSON object shaped like:
29
31
  "entries": [
30
32
  {
31
33
  "id": "a1b2c3d4",
32
- "source": "the original slug / git URL / local path the skill was installed from",
34
+ "source": "the original slug / git URL / local path the skill or server was installed from",
33
35
  "sourceType": "skills.sh | git | local",
34
36
  "installedPath": "final path after promote, or null if only held in quarantine",
35
37
  "quarantinePath": "path to the quarantine sandbox this entry was gated from",
@@ -37,11 +39,19 @@ is a JSON object shaped like:
37
39
  "license": "detected license string, or null",
38
40
  "safetyVerdict": "pass | warn | block",
39
41
  "safetyFindings": ["human-readable safety findings, one per string"],
40
- "overlapTop": [{ "skill": "nearest-existing-skill-name", "score": 0.0 }],
42
+ "overlapTop": [{ "skill": "nearest-existing-skill-or-server-name", "score": 0.0 }],
41
43
  "suggestedVerb": "DEFER | ABSORB | FORK | REJECT | WATCH | null"
42
44
  },
43
45
  "status": "pending | ingested | dismissed",
44
- "createdAt": "ISO-8601 timestamp"
46
+ "createdAt": "ISO-8601 timestamp",
47
+ "artifactType": "skill | mcp (optional — absent means 'skill')",
48
+ "capabilities": {
49
+ "tools": ["statically-extracted tool names — mcp entries only, optional field"],
50
+ "resources": ["statically-extracted resource templates/URIs"],
51
+ "prompts": ["statically-extracted prompt names"],
52
+ "transport": "stdio | http (optional, best-effort)",
53
+ "declaredConfidence": "high | partial | none"
54
+ }
45
55
  }
46
56
  ]
47
57
  }
@@ -52,9 +62,92 @@ Pick the entry with `"status": "pending"` whose `installedPath` (or `quarantineP
52
62
  user and ask which to process, or work through them one at a time — don't silently drain
53
63
  the whole queue.
54
64
 
55
- If there is no matching queue entry at all (you were pointed straight at a skill directory
56
- with no CLI queue involved), that's fine — do the same evaluation, just skip the "close the
57
- entry" step at the end since there's nothing to close.
65
+ If there is no matching queue entry at all (you were pointed straight at a skill or server
66
+ directory with no CLI queue involved), that's fine — do the same evaluation, just skip the
67
+ "close the entry" step at the end since there's nothing to close.
68
+
69
+ Check the entry's `artifactType` before continuing:
70
+
71
+ - **`"skill"` or absent** — this is a skill candidate; continue with §2–7 below.
72
+ - **`"mcp"`** — this is an MCP server candidate; skip §2–7 and follow **"If artifactType is
73
+ `mcp`"** immediately below instead. (If you have no queue entry to check, infer it: a
74
+ directory with a `SKILL.md` is a skill; a directory/package with an `.mcp.json`/
75
+ `mcp.json`, an MCP-server-shaped `package.json`, or an extracted npm tarball with no
76
+ `SKILL.md` is an MCP server.)
77
+
78
+ ---
79
+
80
+ ## If artifactType is `"mcp"`
81
+
82
+ The target is an MCP **server**, not a skill — the decide/act/record steps below replace
83
+ §2–7 for this entry. The five-verb matrix, license triage, and record/close mechanics are
84
+ the same ones §2–7 use for skills; only what you're evaluating and where you act changes.
85
+
86
+ ### Gather context — statically only, always
87
+
88
+ - **Read the entry's `capabilities` field** (introduced in skill-forge v0.6):
89
+ `{ tools, resources, prompts, transport?, declaredConfidence }`, a **statically-extracted**
90
+ profile — tool/resource/prompt names parsed from the candidate's `package.json`, any
91
+ shipped `.mcp.json`/manifest, and MCP SDK source-text patterns (e.g.
92
+ `server.tool("name", ...)`, `setRequestHandler(ListToolsRequestSchema, ...)`,
93
+ `server.resource(...)`, `server.prompt(...)`). It is never derived by running the server.
94
+ - **Do not run or install the server to inspect it.** No `npm install`, no executing its
95
+ binary or entry point, no invoking its tools to see what they do. If `capabilities` is
96
+ absent, empty, or `declaredConfidence` is `"partial"`/`"none"`, read more source
97
+ statically yourself (package.json, README, exported tool/resource/prompt registrations)
98
+ — never execute anything to fill the gap. This is a hard security invariant, not a style
99
+ preference: it mirrors the CLI's own static-only extraction.
100
+ - **Reuse `gate.safetyVerdict` / `gate.safetyFindings`** — the MCP safety scan (unpinned
101
+ `npx`, inline credentials, dangerous launch flags, broad filesystem args) already ran;
102
+ don't re-scan.
103
+ - **Judge redundancy against already-configured servers** using `gate.overlapTop` (nearest
104
+ server-name/package matches) plus your own read of the target mcp config file for
105
+ capability overlap: do any already-configured servers expose the same or near-identical
106
+ tools/resources as this candidate's `capabilities`?
107
+
108
+ ### Decide — same five verbs, applied to a server
109
+
110
+ Weigh the same dimensions as skills (overlap, quality, license, maintenance, fit), reading
111
+ "quality" as `declaredConfidence` plus the safety verdict, and "overlap" as
112
+ tool/resource/prompt redundancy with an already-configured server:
113
+
114
+ - **DEFER** — genuinely new capability, cleanly scoped; keep the promoted config entry
115
+ exactly as installed.
116
+ - **ABSORB** — overlaps partially with something already configured but adds real
117
+ capability; keep it, but **tighten its config first** — trim `env` to only the variables
118
+ its declared tools actually need, narrow broad `args` (e.g. a filesystem root), and
119
+ record which values you removed or narrowed.
120
+ - **FORK** — worth keeping but its default config doesn't fit house convention (wrong
121
+ scope, wrong invocation style, name collision); adjust the config to fit rather than
122
+ installing it verbatim.
123
+ - **REJECT** — duplicates an already-configured server's capability, fails the license
124
+ triage, or `gate.safetyVerdict` is `"block"`; **remove the server entry** from the
125
+ target mcp config with a documented edit (state which entry you removed and why).
126
+ - **WATCH** — promising but not ready to trust (e.g. `declaredConfidence: "none"` and you
127
+ can't determine enough statically), or upstream looks immature; leave the config as-is
128
+ (or don't promote it) and leave a WATCH note — don't silently drop it.
129
+
130
+ License triage (§4 below) applies unchanged: classify `gate.license` before committing to
131
+ ABSORB or FORK, and never ABSORB/FORK on a copyleft, none-stated, or restrictive license
132
+ without the user's explicit sign-off.
133
+
134
+ ### Act
135
+
136
+ Apply the config change (or deliberate non-change) implied by your verb directly to the
137
+ promoted mcp config file — the file the CLI's promote step wrote to (see `installedPath`
138
+ on the entry, or its `--mcp-target` resolution). Edit only the `mcpServers`/`servers` entry
139
+ for this candidate; never touch other servers' entries in the same file. Verify the file
140
+ still parses as valid JSON and the kept/tightened entry's `command`/`args`/`env` shape is
141
+ still well-formed — you're validating the *config*, not spawning the server.
142
+
143
+ ### Record and close the queue entry
144
+
145
+ Record the same fields §6 asks for (candidate name/source, license class, verb chosen,
146
+ what actually changed in the config, reasoning, "n/a" where nothing applies), then close
147
+ the queue entry exactly as in §6's "Close the queue entry": set `status` to `"ingested"`
148
+ once recorded, or `"dismissed"` if the user declined. Report back per §7.
149
+
150
+ ---
58
151
 
59
152
  ## 2. Gather context
60
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhize/skill-forge",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -42,9 +42,12 @@
42
42
  "commander": "^12.1.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/node": "^22.10.5",
46
- "tsup": "^8.3.5",
47
- "typescript": "^5.7.3",
48
- "vitest": "^2.1.8"
45
+ "@types/node": "^26.1.1",
46
+ "tsup": "^8.5.1",
47
+ "typescript": "^7.0.2",
48
+ "vitest": "^4.1.10"
49
+ },
50
+ "overrides": {
51
+ "esbuild": "0.28.1"
49
52
  }
50
53
  }