@dforge-core/dforge-mcp 0.1.13 → 0.2.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.
@@ -42,20 +42,28 @@ Sidebar also gives you right-click commands: **Pack Module**, **Install Module t
42
42
 
43
43
  ## Path 3 — AI co-pilot, wizard-driven
44
44
 
45
- Claude Code (or Cursor / Zed) with `dforge-mcp` connected. You describe what you want; the AI walks you through six phases via MCP tool calls, pausing at each gate for your approval.
45
+ Claude Code (or Cursor / Zed) with `dforge-mcp` connected. You describe what you want; the AI walks you through seven phases (0-6) via MCP tool calls, pausing at each gate for your approval. Guidance ships as four skills — a router plus one per lifecycle stage — so only the active stage is loaded.
46
46
 
47
47
  Setup once:
48
48
 
49
49
  ```bash
50
50
  claude mcp add dforge --scope user -- npx -y @dforge-core/dforge-mcp
51
- # Resolve actual latest from npm, then pin jsdelivr URL to it.
52
- # (jsdelivr's @latest endpoint caches 6-12h; pinning the version skips that.)
53
- VERSION=$(npm view @dforge-core/dforge-mcp version)
54
- mkdir -p ~/.claude/skills/dforge-mcp-author
55
- curl -fsSL "https://cdn.jsdelivr.net/npm/@dforge-core/dforge-mcp@${VERSION}/skills/dforge-mcp-author/SKILL.md" \
56
- -o ~/.claude/skills/dforge-mcp-author/SKILL.md
51
+
52
+ # Install the four authoring skills into ~/.claude/skills/
53
+ npx -y -p @dforge-core/dforge-mcp dforge-install-skills
57
54
  ```
58
55
 
56
+ That works as-is on Windows (cmd.exe / PowerShell), macOS and Linux — it's a
57
+ Node script, not bash. From a clone, `npm run install-skills` installs the local
58
+ copy instead. See the README's "Windows notes" for the WSL caveat.
59
+
60
+ | Skill | Stage |
61
+ |---|---|
62
+ | `dforge-mcp-author` | Router — finds the current phase and hands off |
63
+ | `dforge-module-design` | Phase 0 — identity, requirements, design, validation |
64
+ | `dforge-module-build` | Phases 1-5 — entities, behavior, views, security |
65
+ | `dforge-module-ship` | Phase 6 — validate, pack, install |
66
+
59
67
  Restart Claude Code, approve the MCP server on first prompt, then in a new conversation:
60
68
 
61
69
  ```
@@ -66,7 +74,7 @@ The wizard runs:
66
74
 
67
75
  ### Phase 0 — Identity, requirements, design, validation (required)
68
76
 
69
- A documented chain the `dforge-mcp-author` skill enforces — the AI authors each artifact directly (drafts it, you approve, your client writes the file):
77
+ A documented chain the `dforge-module-design` skill enforces — the AI authors each artifact directly (drafts it, you approve, your client writes the file):
70
78
 
71
79
  - **0a Identity** — write `CLAUDE.md` (identity + MCP-first rules + a live status tracker).
72
80
  - **0b Requirements** — intake questions (purpose / users / dependencies / language scope), then write `docs/REQUIREMENTS.md`. **You review it before moving on.**
@@ -148,6 +156,9 @@ VS Code with the [dForge extension](https://github.com/dforge-core/dforge-editor
148
156
 
149
157
  ## Going further
150
158
 
151
- - [SKILL.md](../skills/dforge-mcp-author/SKILL.md) — the full wizard spec the AI follows, including the deterministic backtrack protocol, multi-trigger priority rule, tool-failure protocol, and resume-from-partial-state support
152
- - [README.md](../README.md) — full tool reference (18 tools, 13 resources) + maintainer docs
159
+ - [dforge-mcp-author](../skills/dforge-mcp-author/SKILL.md) — the router: session start, tool inventory, hard rules, tool-failure protocol, resource index
160
+ - [dforge-module-design](../skills/dforge-module-design/SKILL.md) — Phase 0, including the intake guardrails and gap scans
161
+ - [dforge-module-build](../skills/dforge-module-build/SKILL.md) — Phases 1-5, the loading-policy table, core-rules cheat sheet, and the deterministic backtrack protocol
162
+ - [dforge-module-ship](../skills/dforge-module-ship/SKILL.md) — Phase 6 and the install-fix loop
163
+ - [README.md](../README.md) — full tool reference (34 tools) + maintainer docs
153
164
  - [iash44/dForge-core](https://github.com/iash44/dForge-core) — the platform itself: source of truth for the schemas + DSL conventions
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dforge-core/dforge-mcp",
3
- "version": "0.1.13",
4
- "description": "MCP server for dForge module authoring. Exposes scaffold/pack/install tools and schema resources so AI agents (Claude Code, Cursor, Zed) can create and ship dForge modules.",
3
+ "version": "0.2.0",
4
+ "description": "MCP server for dForge module authoring. Exposes 34 scaffold/patch/validate/pack/install tools and schema resources so AI agents (Claude Code, Cursor, Zed) can create and ship dForge modules.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/iash44/dForge-core",
7
7
  "repository": {
@@ -9,13 +9,15 @@
9
9
  "url": "git+https://github.com/dforge-core/dforge-mcp.git"
10
10
  },
11
11
  "bin": {
12
- "dforge-mcp": "dist/server.js"
12
+ "dforge-mcp": "dist/server.js",
13
+ "dforge-install-skills": "scripts/install-skills.mjs"
13
14
  },
14
15
  "files": [
15
16
  "dist/",
16
17
  "docs/",
17
18
  "resources/",
18
19
  "skills/",
20
+ "scripts/install-skills.mjs",
19
21
  "README.md",
20
22
  "CHANGELOG.md"
21
23
  ],
@@ -28,7 +30,8 @@
28
30
  "sync-schemas": "node scripts/vendor-schemas.cjs",
29
31
  "prepublishOnly": "node scripts/vendor-schemas.cjs && tsup",
30
32
  "typecheck": "tsc --noEmit",
31
- "test": "vitest run"
33
+ "test": "vitest run",
34
+ "install-skills": "node scripts/install-skills.mjs"
32
35
  },
33
36
  "dependencies": {
34
37
  "@dforge-core/dforge-cli": "^0.2.7",
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env node
2
+ // Install the dForge authoring skills into the Claude skills directory.
3
+ //
4
+ // The skills ship inside the npm tarball, but Claude Code only looks in
5
+ // <config>/skills — not node_modules — so they have to be copied out. There are
6
+ // four (a router plus three stage skills), and the router's directory also
7
+ // carries the shared references/ + examples/ the MCP server serves as dforge://
8
+ // resources, so hand-copying is error-prone.
9
+ //
10
+ // Written in Node rather than bash so it behaves identically on Windows
11
+ // (cmd.exe, PowerShell), macOS, Linux, Git Bash and WSL. The bash version this
12
+ // replaced could not run in cmd/PowerShell at all, and under WSL it resolved
13
+ // $HOME to the LINUX home — silently installing to /home/you/.claude while
14
+ // Claude Code on Windows read C:\Users\you\.claude.
15
+ //
16
+ // Usage:
17
+ // node scripts/install-skills.mjs # from a local checkout
18
+ // node scripts/install-skills.mjs --from-npm # download the published version
19
+ // DEST=/some/where node scripts/install-skills.mjs
20
+ //
21
+ // npm run install-skills
22
+ // npm run install-skills -- --from-npm
23
+
24
+ import { spawnSync } from "node:child_process";
25
+ import * as fs from "node:fs";
26
+ import * as os from "node:os";
27
+ import * as path from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+
30
+ const SKILLS = [
31
+ ["dforge-mcp-author", "router — start here; also holds the shared\n references/ and examples/ the MCP server serves"],
32
+ ["dforge-module-design", "Phase 0 — identity, intake, design, validation"],
33
+ ["dforge-module-build", "Phases 1-5 — entities, behavior, views, security"],
34
+ ["dforge-module-ship", "Phase 6 — validate, pack, install-fix loop"],
35
+ ];
36
+
37
+ const PKG = "@dforge-core/dforge-mcp";
38
+ const fromNpm = process.argv.includes("--from-npm");
39
+
40
+ // Piping into `head`/`less` closes our stdout mid-write; without this Node
41
+ // turns that into an unhandled EPIPE and dumps a stack trace over what is
42
+ // otherwise a successful install.
43
+ for (const stream of [process.stdout, process.stderr]) {
44
+ stream.on("error", (e) => {
45
+ if (e.code === "EPIPE") process.exit(0);
46
+ throw e;
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Where Claude Code looks for skills. `CLAUDE_CONFIG_DIR` wins when set;
52
+ * otherwise `<home>/.claude/skills`. os.homedir() is the point of this being a
53
+ * Node script — on Windows it's %USERPROFILE% regardless of which shell (or
54
+ * shell emulator) invoked us.
55
+ */
56
+ function defaultDest() {
57
+ if (process.env.DEST) return process.env.DEST;
58
+ const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
59
+ return path.join(configDir, "skills");
60
+ }
61
+
62
+ /** npm is a .cmd shim on Windows, which spawn can only launch through a shell. */
63
+ const NPM = process.platform === "win32" ? "npm.cmd" : "npm";
64
+
65
+ function npm(args, opts = {}) {
66
+ const r = spawnSync(NPM, args, {
67
+ encoding: "utf8",
68
+ shell: process.platform === "win32",
69
+ ...opts,
70
+ });
71
+ if (r.error) {
72
+ throw new Error(`Failed to run \`npm ${args.join(" ")}\`: ${r.error.message}. Is npm on your PATH?`);
73
+ }
74
+ if (r.status !== 0) {
75
+ throw new Error(`\`npm ${args.join(" ")}\` failed (exit ${r.status}):\n${r.stderr || r.stdout}`);
76
+ }
77
+ return (r.stdout || "").trim();
78
+ }
79
+
80
+ /**
81
+ * Download + unpack the published tarball into a temp dir, returning its
82
+ * skills/ path. Uses `npm pack` (which fetches only this package, not its
83
+ * ~35 MB native CLI dependency) plus `tar`, which ships with Windows 10 1803+,
84
+ * macOS and every Linux.
85
+ */
86
+ function fetchFromNpm(tmp) {
87
+ // Resolve the real latest version rather than relying on a CDN alias that
88
+ // caches for hours after a publish and would serve stale skills.
89
+ const version = npm(["view", PKG, "version"]);
90
+ process.stdout.write(`Fetching ${PKG}@${version} …\n`);
91
+ npm(["pack", `${PKG}@${version}`, "--pack-destination", tmp], { cwd: tmp });
92
+
93
+ const tarball = fs.readdirSync(tmp).find((f) => f.endsWith(".tgz"));
94
+ if (!tarball) throw new Error(`npm pack produced no .tgz in ${tmp}`);
95
+
96
+ const r = spawnSync("tar", ["-xzf", path.join(tmp, tarball), "-C", tmp], { encoding: "utf8" });
97
+ if (r.error || r.status !== 0) {
98
+ throw new Error(
99
+ `Could not extract ${tarball}: ${r.error?.message ?? r.stderr}\n` +
100
+ "`tar` is required (built into Windows 10 1803+, macOS and Linux). " +
101
+ "Alternatively clone the repo and run this script without --from-npm.",
102
+ );
103
+ }
104
+ return path.join(tmp, "package", "skills");
105
+ }
106
+
107
+ function main() {
108
+ const dest = defaultDest();
109
+ let tmp;
110
+ let src;
111
+
112
+ try {
113
+ if (fromNpm) {
114
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), "dforge-skills-"));
115
+ src = fetchFromNpm(tmp);
116
+ } else {
117
+ // Relative to this file, so it works from any cwd.
118
+ const here = path.dirname(fileURLToPath(import.meta.url));
119
+ src = path.join(here, "..", "skills");
120
+ }
121
+
122
+ if (!fs.existsSync(src)) {
123
+ throw new Error(
124
+ `No skills directory at ${src}.` +
125
+ (fromNpm ? "" : " Run with --from-npm to install from the published package instead."),
126
+ );
127
+ }
128
+
129
+ fs.mkdirSync(dest, { recursive: true });
130
+ let installed = 0;
131
+ for (const [skill] of SKILLS) {
132
+ const from = path.join(src, skill);
133
+ if (!fs.existsSync(from)) {
134
+ process.stderr.write(` ! skipping ${skill} (not found in ${src})\n`);
135
+ continue;
136
+ }
137
+ // Replace wholesale: a stale reference file left behind is worse than a
138
+ // missing one, because the agent will happily author against it.
139
+ fs.rmSync(path.join(dest, skill), { recursive: true, force: true });
140
+ fs.cpSync(from, path.join(dest, skill), { recursive: true });
141
+ process.stdout.write(` \u2713 ${skill}\n`);
142
+ installed++;
143
+ }
144
+
145
+ if (installed === 0) throw new Error(`No skills were installed from ${src}.`);
146
+
147
+ process.stdout.write(
148
+ `\nInstalled ${installed} skill${installed === 1 ? "" : "s"} to ${dest}\n\n`,
149
+ );
150
+ for (const [skill, blurb] of SKILLS) {
151
+ process.stdout.write(` ${skill.padEnd(21)} ${blurb}\n`);
152
+ }
153
+ process.stdout.write(
154
+ "\nRe-run after every dforge-mcp upgrade. The skill version is not checked at\n" +
155
+ "runtime, so stale skills against new tools will misroute calls.\n",
156
+ );
157
+ } catch (e) {
158
+ process.stderr.write(`error: ${e.message}\n`);
159
+ process.exitCode = 1;
160
+ } finally {
161
+ if (tmp) fs.rmSync(tmp, { recursive: true, force: true });
162
+ }
163
+ }
164
+
165
+ main();