forgecraft-mcp 0.2.0 → 0.3.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/README.md +25 -5
- package/dist/analyzers/language-detector.d.ts +17 -0
- package/dist/analyzers/language-detector.d.ts.map +1 -0
- package/dist/analyzers/language-detector.js +89 -0
- package/dist/analyzers/language-detector.js.map +1 -0
- package/dist/analyzers/package-json.d.ts.map +1 -1
- package/dist/analyzers/package-json.js +5 -5
- package/dist/analyzers/package-json.js.map +1 -1
- package/dist/analyzers/project-context.d.ts +23 -0
- package/dist/analyzers/project-context.d.ts.map +1 -0
- package/dist/analyzers/project-context.js +181 -0
- package/dist/analyzers/project-context.js.map +1 -0
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/registry/composer.d.ts +3 -1
- package/dist/registry/composer.d.ts.map +1 -1
- package/dist/registry/composer.js +28 -0
- package/dist/registry/composer.js.map +1 -1
- package/dist/registry/loader.d.ts.map +1 -1
- package/dist/registry/loader.js +65 -1
- package/dist/registry/loader.js.map +1 -1
- package/dist/registry/mcp-discovery.d.ts +82 -0
- package/dist/registry/mcp-discovery.d.ts.map +1 -0
- package/dist/registry/mcp-discovery.js +203 -0
- package/dist/registry/mcp-discovery.js.map +1 -0
- package/dist/registry/renderer.d.ts +19 -2
- package/dist/registry/renderer.d.ts.map +1 -1
- package/dist/registry/renderer.js +64 -2
- package/dist/registry/renderer.js.map +1 -1
- package/dist/shared/errors/index.d.ts +4 -0
- package/dist/shared/errors/index.d.ts.map +1 -1
- package/dist/shared/errors/index.js +6 -0
- package/dist/shared/errors/index.js.map +1 -1
- package/dist/shared/filesystem.d.ts +45 -0
- package/dist/shared/filesystem.d.ts.map +1 -0
- package/dist/shared/filesystem.js +122 -0
- package/dist/shared/filesystem.js.map +1 -0
- package/dist/shared/types.d.ts +92 -1
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +6 -0
- package/dist/shared/types.js.map +1 -1
- package/dist/tools/configure-mcp.d.ts +24 -0
- package/dist/tools/configure-mcp.d.ts.map +1 -1
- package/dist/tools/configure-mcp.js +123 -24
- package/dist/tools/configure-mcp.js.map +1 -1
- package/dist/tools/generate-claude-md.d.ts +1 -0
- package/dist/tools/generate-claude-md.d.ts.map +1 -1
- package/dist/tools/generate-claude-md.js +23 -57
- package/dist/tools/generate-claude-md.js.map +1 -1
- package/dist/tools/get-reference.d.ts +28 -0
- package/dist/tools/get-reference.d.ts.map +1 -0
- package/dist/tools/get-reference.js +63 -0
- package/dist/tools/get-reference.js.map +1 -0
- package/dist/tools/list.d.ts +18 -2
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/list.js +74 -2
- package/dist/tools/list.js.map +1 -1
- package/dist/tools/refresh-project.d.ts.map +1 -1
- package/dist/tools/refresh-project.js +8 -10
- package/dist/tools/refresh-project.js.map +1 -1
- package/dist/tools/scaffold.d.ts +4 -0
- package/dist/tools/scaffold.d.ts.map +1 -1
- package/dist/tools/scaffold.js +58 -31
- package/dist/tools/scaffold.js.map +1 -1
- package/dist/tools/setup-project.d.ts.map +1 -1
- package/dist/tools/setup-project.js +5 -1
- package/dist/tools/setup-project.js.map +1 -1
- package/package.json +7 -3
- package/templates/analytics/mcp-servers.yaml +11 -0
- package/templates/api/mcp-servers.yaml +13 -0
- package/templates/api/skills.yaml +54 -0
- package/templates/cli/mcp-servers.yaml +11 -0
- package/templates/data-lineage/instructions.yaml +28 -0
- package/templates/data-lineage/mcp-servers.yaml +22 -0
- package/templates/data-pipeline/mcp-servers.yaml +13 -0
- package/templates/data-pipeline/skills.yaml +56 -0
- package/templates/fintech/mcp-servers.yaml +13 -0
- package/templates/fintech/skills.yaml +35 -0
- package/templates/game/mcp-servers.yaml +11 -0
- package/templates/healthcare/mcp-servers.yaml +13 -0
- package/templates/healthcare/skills.yaml +35 -0
- package/templates/hipaa/instructions.yaml +41 -0
- package/templates/hipaa/mcp-servers.yaml +13 -0
- package/templates/hipaa/skills.yaml +39 -0
- package/templates/infra/mcp-servers.yaml +20 -0
- package/templates/library/mcp-servers.yaml +20 -0
- package/templates/medallion-architecture/instructions.yaml +41 -0
- package/templates/medallion-architecture/mcp-servers.yaml +22 -0
- package/templates/ml/mcp-servers.yaml +11 -0
- package/templates/mobile/mcp-servers.yaml +11 -0
- package/templates/observability-xray/instructions.yaml +40 -0
- package/templates/observability-xray/mcp-servers.yaml +15 -0
- package/templates/realtime/mcp-servers.yaml +13 -0
- package/templates/soc2/instructions.yaml +41 -0
- package/templates/soc2/mcp-servers.yaml +24 -0
- package/templates/social/mcp-servers.yaml +24 -0
- package/templates/state-machine/mcp-servers.yaml +11 -0
- package/templates/universal/hooks.yaml +63 -0
- package/templates/universal/instructions.yaml +41 -118
- package/templates/universal/mcp-servers.yaml +38 -0
- package/templates/universal/nfr.yaml +1 -1
- package/templates/universal/reference.yaml +111 -0
- package/templates/universal/review.yaml +2 -2
- package/templates/universal/skills.yaml +106 -0
- package/templates/web-react/mcp-servers.yaml +20 -0
- package/templates/web-react/skills.yaml +56 -0
- package/templates/web-static/mcp-servers.yaml +20 -0
- package/templates/web3/mcp-servers.yaml +11 -0
- package/templates/zero-trust/instructions.yaml +41 -0
- package/templates/zero-trust/mcp-servers.yaml +15 -0
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
* configure_mcp tool handler.
|
|
3
3
|
*
|
|
4
4
|
* Generates .claude/settings.json with recommended MCP servers based on tags.
|
|
5
|
+
* Uses the McpDiscoveryService to load curated servers from YAML templates
|
|
6
|
+
* and optionally fetch from a remote registry at setup time.
|
|
5
7
|
*/
|
|
6
8
|
import { z } from "zod";
|
|
7
9
|
import { mkdirSync, writeFileSync, existsSync, readFileSync } from "node:fs";
|
|
8
10
|
import { join } from "node:path";
|
|
9
11
|
import { ALL_TAGS } from "../shared/types.js";
|
|
12
|
+
import { DefaultMcpDiscoveryService } from "../registry/mcp-discovery.js";
|
|
10
13
|
// ── Schema ───────────────────────────────────────────────────────────
|
|
11
14
|
export const configureMcpSchema = z.object({
|
|
12
15
|
tags: z
|
|
@@ -29,36 +32,71 @@ export const configureMcpSchema = z.object({
|
|
|
29
32
|
.default(true)
|
|
30
33
|
.describe("If true, adds permissions.allow entries for all configured MCP servers " +
|
|
31
34
|
"so tool invocations are auto-approved without manual confirmation."),
|
|
35
|
+
include_remote: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.default(false)
|
|
38
|
+
.describe("If true, also queries a remote MCP server registry for additional recommendations. " +
|
|
39
|
+
"Requires FORGECRAFT_MCP_REGISTRY_URL env var or remote_registry_url parameter."),
|
|
40
|
+
remote_registry_url: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Override URL for the remote MCP server registry."),
|
|
44
|
+
max_servers: z
|
|
45
|
+
.number()
|
|
46
|
+
.int()
|
|
47
|
+
.positive()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Maximum number of MCP servers to configure. " +
|
|
50
|
+
"When exceeded, filters by tier priority (core > recommended > optional)."),
|
|
32
51
|
});
|
|
33
|
-
// ── Recommended Servers per Tag ──────────────────────────────────────
|
|
34
|
-
const TAG_SERVERS = {
|
|
35
|
-
UNIVERSAL: {
|
|
36
|
-
forgecraft: {
|
|
37
|
-
command: "npx",
|
|
38
|
-
args: ["-y", "forgecraft-mcp"],
|
|
39
|
-
},
|
|
40
|
-
codeseeker: {
|
|
41
|
-
command: "npx",
|
|
42
|
-
args: ["-y", "codeseeker"],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
52
|
// ── Handler ──────────────────────────────────────────────────────────
|
|
53
|
+
/** Injected discovery service for testing. Defaults to DefaultMcpDiscoveryService. */
|
|
54
|
+
let injectedDiscoveryService;
|
|
55
|
+
/**
|
|
56
|
+
* Inject a custom discovery service (for testing).
|
|
57
|
+
*
|
|
58
|
+
* @param service - Discovery service to use, or undefined to reset to default
|
|
59
|
+
*/
|
|
60
|
+
export function setDiscoveryService(service) {
|
|
61
|
+
injectedDiscoveryService = service;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Generate .claude/settings.json with discovered MCP servers for active tags.
|
|
65
|
+
*
|
|
66
|
+
* @param args - Validated tool input
|
|
67
|
+
* @returns MCP tool response with configuration summary
|
|
68
|
+
*/
|
|
47
69
|
export async function configureMcpHandler(args) {
|
|
48
70
|
const tags = args.tags;
|
|
49
|
-
|
|
71
|
+
const discovery = injectedDiscoveryService ?? new DefaultMcpDiscoveryService();
|
|
72
|
+
// ── Discover servers ─────────────────────────────────────────────
|
|
73
|
+
const discoveryOptions = {
|
|
74
|
+
includeRemote: args.include_remote,
|
|
75
|
+
remoteRegistryUrl: args.remote_registry_url,
|
|
76
|
+
};
|
|
77
|
+
let recommendations = await discovery.discoverServers(tags, discoveryOptions);
|
|
78
|
+
// Apply max_servers limit with tier-based priority filtering
|
|
79
|
+
if (args.max_servers && recommendations.length > args.max_servers) {
|
|
80
|
+
recommendations = filterByTierPriority(recommendations, args.max_servers);
|
|
81
|
+
}
|
|
82
|
+
// Convert recommendations to server config map
|
|
50
83
|
const servers = {};
|
|
51
|
-
for (const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
84
|
+
for (const rec of recommendations) {
|
|
85
|
+
servers[rec.name] = {
|
|
86
|
+
command: rec.command,
|
|
87
|
+
args: rec.args,
|
|
88
|
+
...(rec.env ? { env: rec.env } : {}),
|
|
89
|
+
source: rec.source,
|
|
90
|
+
description: rec.description,
|
|
91
|
+
};
|
|
56
92
|
}
|
|
57
|
-
// Add custom servers
|
|
93
|
+
// Add custom servers (user-provided, highest priority)
|
|
58
94
|
if (args.custom_servers) {
|
|
59
|
-
Object.
|
|
95
|
+
for (const [name, config] of Object.entries(args.custom_servers)) {
|
|
96
|
+
servers[name] = { ...config, source: "custom" };
|
|
97
|
+
}
|
|
60
98
|
}
|
|
61
|
-
// Build settings.json
|
|
99
|
+
// ── Build settings.json ──────────────────────────────────────────
|
|
62
100
|
const mcpConfig = {};
|
|
63
101
|
for (const [name, config] of Object.entries(servers)) {
|
|
64
102
|
mcpConfig[name] = {
|
|
@@ -78,7 +116,7 @@ export async function configureMcpHandler(args) {
|
|
|
78
116
|
if (permissionRules.length > 0) {
|
|
79
117
|
settings["permissions"] = { allow: permissionRules };
|
|
80
118
|
}
|
|
81
|
-
// Handle existing settings
|
|
119
|
+
// ── Handle existing settings ─────────────────────────────────────
|
|
82
120
|
const settingsDir = join(args.project_dir, ".claude");
|
|
83
121
|
const settingsPath = join(settingsDir, "settings.json");
|
|
84
122
|
let merged = settings;
|
|
@@ -107,21 +145,82 @@ export async function configureMcpHandler(args) {
|
|
|
107
145
|
}
|
|
108
146
|
mkdirSync(settingsDir, { recursive: true });
|
|
109
147
|
writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
148
|
+
// ── Build response ───────────────────────────────────────────────
|
|
110
149
|
const serverNames = Object.keys(servers);
|
|
150
|
+
const bySource = groupBySource(servers);
|
|
111
151
|
return {
|
|
112
152
|
content: [
|
|
113
153
|
{
|
|
114
154
|
type: "text",
|
|
115
155
|
text: `MCP configuration written to \`.claude/settings.json\`.\n\n` +
|
|
116
156
|
`**Servers configured (${serverNames.length}):**\n` +
|
|
117
|
-
|
|
157
|
+
formatServerList(servers) +
|
|
158
|
+
(bySource["remote"] && bySource["remote"] > 0
|
|
159
|
+
? `\n\n📡 ${bySource["remote"]} server(s) discovered from remote registry.`
|
|
160
|
+
: "") +
|
|
118
161
|
(permissionRules.length > 0
|
|
119
162
|
? `\n\n**Auto-approved (${permissionRules.length}):**\n` +
|
|
120
163
|
permissionRules.map((r) => `- \`${r}\``).join("\n")
|
|
121
164
|
: "") +
|
|
165
|
+
(serverNames.length > 5
|
|
166
|
+
? `\n\n💡 **Token note:** ${serverNames.length} servers add ~${serverNames.length * 500} tokens to context per conversation. Use \`max_servers\` to limit if needed.`
|
|
167
|
+
: "") +
|
|
122
168
|
`\n\n⚠️ Restart required to pick up MCP server changes.`,
|
|
123
169
|
},
|
|
124
170
|
],
|
|
125
171
|
};
|
|
126
172
|
}
|
|
173
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
174
|
+
/**
|
|
175
|
+
* Format the server list for display, grouped by source.
|
|
176
|
+
*
|
|
177
|
+
* @param servers - Server config map with source metadata
|
|
178
|
+
* @returns Markdown-formatted server list
|
|
179
|
+
*/
|
|
180
|
+
function formatServerList(servers) {
|
|
181
|
+
return Object.entries(servers)
|
|
182
|
+
.map(([name, config]) => {
|
|
183
|
+
const sourceLabel = config.source ? ` [${config.source}]` : "";
|
|
184
|
+
const descLabel = config.description ? ` — ${config.description}` : "";
|
|
185
|
+
return `- \`${name}\`${sourceLabel}: \`${config.command} ${config.args.join(" ")}\`${descLabel}`;
|
|
186
|
+
})
|
|
187
|
+
.join("\n");
|
|
188
|
+
}
|
|
189
|
+
/** Tier priority for sorting (lower = higher priority). */
|
|
190
|
+
const TIER_PRIORITY = {
|
|
191
|
+
core: 0,
|
|
192
|
+
recommended: 1,
|
|
193
|
+
optional: 2,
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Filter recommendations by tier priority, keeping up to maxCount servers.
|
|
197
|
+
* Core servers are kept first, then recommended, then optional.
|
|
198
|
+
*
|
|
199
|
+
* @param recommendations - Full list of discovered servers
|
|
200
|
+
* @param maxCount - Maximum number of servers to keep
|
|
201
|
+
* @returns Filtered list sorted by tier priority
|
|
202
|
+
*/
|
|
203
|
+
function filterByTierPriority(recommendations, maxCount) {
|
|
204
|
+
return [...recommendations]
|
|
205
|
+
.sort((a, b) => {
|
|
206
|
+
const aTier = TIER_PRIORITY[a.tier ?? "recommended"] ?? 1;
|
|
207
|
+
const bTier = TIER_PRIORITY[b.tier ?? "recommended"] ?? 1;
|
|
208
|
+
return aTier - bTier;
|
|
209
|
+
})
|
|
210
|
+
.slice(0, maxCount);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Count servers by source.
|
|
214
|
+
*
|
|
215
|
+
* @param servers - Server config map with source metadata
|
|
216
|
+
* @returns Counts per source type
|
|
217
|
+
*/
|
|
218
|
+
function groupBySource(servers) {
|
|
219
|
+
const counts = {};
|
|
220
|
+
for (const config of Object.values(servers)) {
|
|
221
|
+
const source = config.source ?? "unknown";
|
|
222
|
+
counts[source] = (counts[source] ?? 0) + 1;
|
|
223
|
+
}
|
|
224
|
+
return counts;
|
|
225
|
+
}
|
|
127
226
|
//# sourceMappingURL=configure-mcp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configure-mcp.js","sourceRoot":"","sources":["../../src/tools/configure-mcp.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"configure-mcp.js","sourceRoot":"","sources":["../../src/tools/configure-mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates instruction files for AI assistants (Claude, Cursor, Copilot, Windsurf, Cline, Aider).
|
|
5
5
|
* Replaces the former generate_claude_md tool with multi-target support.
|
|
6
|
+
* Always merges with existing files by default to preserve user custom sections.
|
|
6
7
|
*/
|
|
7
8
|
import { z } from "zod";
|
|
8
9
|
export declare const generateInstructionsSchema: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generate-claude-md.d.ts","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;EAqBrC,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EAA6B,CAAC;AAIjE,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAC/C,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAoE7D;AAED,2DAA2D;AAC3D,eAAO,MAAM,uBAAuB,oCAA8B,CAAC"}
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates instruction files for AI assistants (Claude, Cursor, Copilot, Windsurf, Cline, Aider).
|
|
5
5
|
* Replaces the former generate_claude_md tool with multi-target support.
|
|
6
|
+
* Always merges with existing files by default to preserve user custom sections.
|
|
6
7
|
*/
|
|
7
8
|
import { z } from "zod";
|
|
8
|
-
import {
|
|
9
|
+
import { writeFileSync, mkdirSync } from "node:fs";
|
|
9
10
|
import { join, dirname } from "node:path";
|
|
10
11
|
import { ALL_TAGS, ALL_OUTPUT_TARGETS, OUTPUT_TARGET_CONFIGS, DEFAULT_OUTPUT_TARGET } from "../shared/types.js";
|
|
11
12
|
import { loadAllTemplatesWithExtras, loadUserOverrides } from "../registry/loader.js";
|
|
12
13
|
import { composeTemplates } from "../registry/composer.js";
|
|
13
14
|
import { renderInstructionFile } from "../registry/renderer.js";
|
|
15
|
+
import { writeInstructionFileWithMerge } from "../shared/filesystem.js";
|
|
16
|
+
import { detectLanguage } from "../analyzers/language-detector.js";
|
|
17
|
+
import { detectProjectContext } from "../analyzers/project-context.js";
|
|
14
18
|
// ── Schema ───────────────────────────────────────────────────────────
|
|
15
19
|
export const generateInstructionsSchema = z.object({
|
|
16
20
|
tags: z
|
|
@@ -31,8 +35,8 @@ export const generateInstructionsSchema = z.object({
|
|
|
31
35
|
.describe("AI assistant targets to generate for. Defaults to ['claude']. Options: claude, cursor, copilot, windsurf, cline, aider."),
|
|
32
36
|
merge_with_existing: z
|
|
33
37
|
.boolean()
|
|
34
|
-
.default(
|
|
35
|
-
.describe("If true, merge with existing instruction files instead of replacing."),
|
|
38
|
+
.default(true)
|
|
39
|
+
.describe("If true, merge with existing instruction files instead of replacing. Preserves custom sections added by the user. Default: true."),
|
|
36
40
|
});
|
|
37
41
|
/** @deprecated Use generateInstructionsSchema instead. */
|
|
38
42
|
export const generateClaudeMdSchema = generateInstructionsSchema;
|
|
@@ -47,39 +51,38 @@ export async function generateInstructionsHandler(args) {
|
|
|
47
51
|
const composed = composeTemplates(tags, templateSets, {
|
|
48
52
|
config: userConfig ?? undefined,
|
|
49
53
|
});
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
tags
|
|
54
|
-
};
|
|
54
|
+
const detectedLang = args.project_dir ? detectLanguage(args.project_dir) : "typescript";
|
|
55
|
+
const context = args.project_dir
|
|
56
|
+
? detectProjectContext(args.project_dir, args.project_name, detectedLang, tags)
|
|
57
|
+
: { projectName: args.project_name, language: detectedLang, tags };
|
|
55
58
|
const filesWritten = [];
|
|
56
59
|
const targetSummaries = [];
|
|
57
60
|
for (const target of targets) {
|
|
58
61
|
const targetConfig = OUTPUT_TARGET_CONFIGS[target];
|
|
59
|
-
|
|
60
|
-
// Handle merge with existing
|
|
61
|
-
if (args.merge_with_existing && args.project_dir) {
|
|
62
|
-
const existingPath = resolveTargetPath(args.project_dir, target);
|
|
63
|
-
if (existsSync(existingPath)) {
|
|
64
|
-
const existing = readFileSync(existingPath, "utf-8");
|
|
65
|
-
content = mergeInstructionFile(existing, content);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
62
|
+
const content = renderInstructionFile(composed.instructionBlocks, context, target);
|
|
68
63
|
// Write to disk if project_dir provided
|
|
69
64
|
if (args.project_dir) {
|
|
70
65
|
const targetPath = resolveTargetPath(args.project_dir, target);
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
if (args.merge_with_existing) {
|
|
67
|
+
writeInstructionFileWithMerge(targetPath, content);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
71
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
72
|
+
}
|
|
73
73
|
filesWritten.push(targetPath);
|
|
74
74
|
targetSummaries.push(`- **${targetConfig.displayName}**: \`${targetConfig.directory ? targetConfig.directory + "/" : ""}${targetConfig.filename}\``);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
if (args.project_dir && filesWritten.length > 0) {
|
|
78
|
+
const mergeNote = args.merge_with_existing
|
|
79
|
+
? "\n\n> Custom sections from existing files have been preserved."
|
|
80
|
+
: "";
|
|
78
81
|
return {
|
|
79
82
|
content: [
|
|
80
83
|
{
|
|
81
84
|
type: "text",
|
|
82
|
-
text: `# Instruction Files Generated\n\n**Tags:** ${tags.map((t) => `[${t}]`).join(" ")}\n**Blocks:** ${composed.instructionBlocks.length}\n\n## Files Written\n${targetSummaries.join("\n")}\n\n⚠️ Restart may be required to pick up changes.`,
|
|
85
|
+
text: `# Instruction Files Generated\n\n**Tags:** ${tags.map((t) => `[${t}]`).join(" ")}\n**Blocks:** ${composed.instructionBlocks.length}\n\n## Files Written\n${targetSummaries.join("\n")}${mergeNote}\n\n⚠️ Restart may be required to pick up changes.`,
|
|
83
86
|
},
|
|
84
87
|
],
|
|
85
88
|
};
|
|
@@ -107,41 +110,4 @@ function resolveTargetPath(projectDir, target) {
|
|
|
107
110
|
}
|
|
108
111
|
return join(projectDir, config.filename);
|
|
109
112
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Merge generated instruction file with existing one.
|
|
112
|
-
* Keeps any custom sections from the existing file.
|
|
113
|
-
*/
|
|
114
|
-
function mergeInstructionFile(existing, generated) {
|
|
115
|
-
const existingLines = existing.split("\n");
|
|
116
|
-
const generatedLines = generated.split("\n");
|
|
117
|
-
// Find custom sections (sections not in generated)
|
|
118
|
-
const generatedHeaders = new Set(generatedLines
|
|
119
|
-
.filter((l) => l.startsWith("## ") || l.startsWith("### "))
|
|
120
|
-
.map((l) => l.trim()));
|
|
121
|
-
const customSections = [];
|
|
122
|
-
let inCustomSection = false;
|
|
123
|
-
let currentSection = [];
|
|
124
|
-
for (const line of existingLines) {
|
|
125
|
-
if (line.startsWith("## ") || line.startsWith("### ")) {
|
|
126
|
-
if (inCustomSection && currentSection.length > 0) {
|
|
127
|
-
customSections.push(currentSection.join("\n"));
|
|
128
|
-
}
|
|
129
|
-
inCustomSection = !generatedHeaders.has(line.trim());
|
|
130
|
-
currentSection = inCustomSection ? [line] : [];
|
|
131
|
-
}
|
|
132
|
-
else if (inCustomSection) {
|
|
133
|
-
currentSection.push(line);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (inCustomSection && currentSection.length > 0) {
|
|
137
|
-
customSections.push(currentSection.join("\n"));
|
|
138
|
-
}
|
|
139
|
-
// Append custom sections to generated content
|
|
140
|
-
if (customSections.length > 0) {
|
|
141
|
-
return (generated +
|
|
142
|
-
"\n\n<!-- Custom Sections (preserved from previous file) -->\n\n" +
|
|
143
|
-
customSections.join("\n\n"));
|
|
144
|
-
}
|
|
145
|
-
return generated;
|
|
146
|
-
}
|
|
147
113
|
//# sourceMappingURL=generate-claude-md.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-claude-md.js","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generate-claude-md.js","sourceRoot":"","sources":["../../src/tools/generate-claude-md.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_design_reference tool handler.
|
|
3
|
+
*
|
|
4
|
+
* Returns design reference patterns (DDD, CQRS, GoF) on demand.
|
|
5
|
+
* These blocks are NOT included in generated instruction files to save tokens —
|
|
6
|
+
* they are served only when explicitly requested.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export declare const getDesignReferenceSchema: z.ZodObject<{
|
|
10
|
+
tags: z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
tags: string[];
|
|
13
|
+
}, {
|
|
14
|
+
tags: string[];
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Handle get_design_reference tool calls.
|
|
18
|
+
*
|
|
19
|
+
* @param args - Validated tool input with tags array
|
|
20
|
+
* @returns Design reference patterns as formatted markdown
|
|
21
|
+
*/
|
|
22
|
+
export declare function getDesignReferenceHandler(args: z.infer<typeof getDesignReferenceSchema>): Promise<{
|
|
23
|
+
content: Array<{
|
|
24
|
+
type: "text";
|
|
25
|
+
text: string;
|
|
26
|
+
}>;
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=get-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-reference.d.ts","sourceRoot":"","sources":["../../src/tools/get-reference.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,wBAAwB;;;;;;EAKnC,CAAC;AAIH;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAC7C,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAyC7D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_design_reference tool handler.
|
|
3
|
+
*
|
|
4
|
+
* Returns design reference patterns (DDD, CQRS, GoF) on demand.
|
|
5
|
+
* These blocks are NOT included in generated instruction files to save tokens —
|
|
6
|
+
* they are served only when explicitly requested.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { ALL_TAGS } from "../shared/types.js";
|
|
10
|
+
import { loadAllTemplates } from "../registry/loader.js";
|
|
11
|
+
import { composeTemplates } from "../registry/composer.js";
|
|
12
|
+
import { renderReference } from "../registry/renderer.js";
|
|
13
|
+
// ── Schema ───────────────────────────────────────────────────────────
|
|
14
|
+
export const getDesignReferenceSchema = z.object({
|
|
15
|
+
tags: z
|
|
16
|
+
.array(z.enum(ALL_TAGS))
|
|
17
|
+
.min(1)
|
|
18
|
+
.describe("Tags to get design reference patterns for."),
|
|
19
|
+
});
|
|
20
|
+
// ── Handler ──────────────────────────────────────────────────────────
|
|
21
|
+
/**
|
|
22
|
+
* Handle get_design_reference tool calls.
|
|
23
|
+
*
|
|
24
|
+
* @param args - Validated tool input with tags array
|
|
25
|
+
* @returns Design reference patterns as formatted markdown
|
|
26
|
+
*/
|
|
27
|
+
export async function getDesignReferenceHandler(args) {
|
|
28
|
+
const tags = args.tags.includes("UNIVERSAL")
|
|
29
|
+
? args.tags
|
|
30
|
+
: ["UNIVERSAL", ...args.tags];
|
|
31
|
+
const templateSets = await loadAllTemplates();
|
|
32
|
+
const composed = composeTemplates(tags, templateSets);
|
|
33
|
+
if (composed.referenceBlocks.length === 0) {
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: "No design reference patterns found for the specified tags.",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const context = {
|
|
44
|
+
projectName: "Project",
|
|
45
|
+
language: "typescript",
|
|
46
|
+
tags,
|
|
47
|
+
};
|
|
48
|
+
const referenceContent = renderReference(composed.referenceBlocks, context);
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `# Design Reference Patterns\n\n` +
|
|
54
|
+
`**Tags:** ${tags.map((t) => `[${t}]`).join(" ")}\n` +
|
|
55
|
+
`**Patterns:** ${composed.referenceBlocks.length}\n\n` +
|
|
56
|
+
`> These patterns are served on demand to save tokens. ` +
|
|
57
|
+
`They are NOT included in your instruction files.\n\n` +
|
|
58
|
+
referenceContent,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=get-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-reference.js","sourceRoot":"","sources":["../../src/tools/get-reference.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,wEAAwE;AAExE,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAA4C,CAAC,CAAC;SAC3D,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,4CAA4C,CAAC;CAC1D,CAAC,CAAC;AAEH,wEAAwE;AAExE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAA8C;IAE9C,MAAM,IAAI,GAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QACjD,CAAC,CAAE,IAAI,CAAC,IAAc;QACtB,CAAC,CAAE,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,CAAW,CAAC;IAE3C,MAAM,YAAY,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,4DAA4D;iBACnE;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG;QACd,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,YAAqB;QAC/B,IAAI;KACL,CAAC;IAEF,MAAM,gBAAgB,GAAG,eAAe,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAE5E,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EACF,iCAAiC;oBACjC,aAAa,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;oBACpD,iBAAiB,QAAQ,CAAC,eAAe,CAAC,MAAM,MAAM;oBACtD,wDAAwD;oBACxD,sDAAsD;oBACtD,gBAAgB;aACnB;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/tools/list.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* list_tags / list_hooks tool handlers.
|
|
2
|
+
* list_tags / list_hooks / list_skills tool handlers.
|
|
3
3
|
*
|
|
4
|
-
* Discovery tools for Claude Code to understand available tags and
|
|
4
|
+
* Discovery tools for Claude Code to understand available tags, hooks, and skills.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
export declare const listTagsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
@@ -12,6 +12,13 @@ export declare const listHooksSchema: z.ZodObject<{
|
|
|
12
12
|
}, {
|
|
13
13
|
tags?: string[] | undefined;
|
|
14
14
|
}>;
|
|
15
|
+
export declare const listSkillsSchema: z.ZodObject<{
|
|
16
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
tags?: string[] | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
tags?: string[] | undefined;
|
|
21
|
+
}>;
|
|
15
22
|
/**
|
|
16
23
|
* List all available tags with descriptions.
|
|
17
24
|
*/
|
|
@@ -30,4 +37,13 @@ export declare function listHooksHandler(args: z.infer<typeof listHooksSchema>):
|
|
|
30
37
|
text: string;
|
|
31
38
|
}>;
|
|
32
39
|
}>;
|
|
40
|
+
/**
|
|
41
|
+
* List all available skills (Claude Code custom commands), optionally filtered by tags.
|
|
42
|
+
*/
|
|
43
|
+
export declare function listSkillsHandler(args: z.infer<typeof listSkillsSchema>): Promise<{
|
|
44
|
+
content: Array<{
|
|
45
|
+
type: "text";
|
|
46
|
+
text: string;
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
33
49
|
//# sourceMappingURL=list.d.ts.map
|
package/dist/tools/list.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,cAAc,gDAAe,CAAC;AAE3C,eAAO,MAAM,eAAe;;;;;;EAK1B,CAAC;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,cAAc,gDAAe,CAAC;AAE3C,eAAO,MAAM,eAAe;;;;;;EAK1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;EAK3B,CAAC;AAyGH;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAAC,CAsBD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GACpC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA6C7D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GACrC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA8C7D"}
|
package/dist/tools/list.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* list_tags / list_hooks tool handlers.
|
|
2
|
+
* list_tags / list_hooks / list_skills tool handlers.
|
|
3
3
|
*
|
|
4
|
-
* Discovery tools for Claude Code to understand available tags and
|
|
4
|
+
* Discovery tools for Claude Code to understand available tags, hooks, and skills.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { ALL_TAGS } from "../shared/types.js";
|
|
@@ -14,6 +14,12 @@ export const listHooksSchema = z.object({
|
|
|
14
14
|
.optional()
|
|
15
15
|
.describe("Filter hooks to specific tags. Omit to list all hooks."),
|
|
16
16
|
});
|
|
17
|
+
export const listSkillsSchema = z.object({
|
|
18
|
+
tags: z
|
|
19
|
+
.array(z.enum(ALL_TAGS))
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Filter skills to specific tags. Omit to list all skills."),
|
|
22
|
+
});
|
|
17
23
|
// ── Tag Descriptions ─────────────────────────────────────────────────
|
|
18
24
|
const TAG_DESCRIPTIONS = {
|
|
19
25
|
UNIVERSAL: {
|
|
@@ -88,6 +94,30 @@ const TAG_DESCRIPTIONS = {
|
|
|
88
94
|
description: "Analytics/reporting — event tracking, dashboards, data warehousing.",
|
|
89
95
|
appliesWhen: "Project includes analytics dashboards, reporting, or event tracking.",
|
|
90
96
|
},
|
|
97
|
+
HIPAA: {
|
|
98
|
+
description: "HIPAA compliance — PII masking templates, encryption checks, audit logging.",
|
|
99
|
+
appliesWhen: "Project handles Protected Health Information requiring HIPAA compliance.",
|
|
100
|
+
},
|
|
101
|
+
SOC2: {
|
|
102
|
+
description: "SOC2 compliance — access control validation, change management, incident response.",
|
|
103
|
+
appliesWhen: "Project requires SOC2 audit readiness (Type I or Type II).",
|
|
104
|
+
},
|
|
105
|
+
"DATA-LINEAGE": {
|
|
106
|
+
description: "Data lineage — enforce 100% field coverage, lineage tracking decorators.",
|
|
107
|
+
appliesWhen: "Project processes data that requires full field-level lineage tracking.",
|
|
108
|
+
},
|
|
109
|
+
"OBSERVABILITY-XRAY": {
|
|
110
|
+
description: "AWS X-Ray observability — auto-add X-Ray instrumentation to Lambdas.",
|
|
111
|
+
appliesWhen: "Project runs on AWS Lambda and requires distributed tracing with X-Ray.",
|
|
112
|
+
},
|
|
113
|
+
"MEDALLION-ARCHITECTURE": {
|
|
114
|
+
description: "Medallion architecture — enforce Bronze=immutable, Silver=validated, Gold=aggregated.",
|
|
115
|
+
appliesWhen: "Project uses a lakehouse/medallion data architecture (Bronze/Silver/Gold).",
|
|
116
|
+
},
|
|
117
|
+
"ZERO-TRUST": {
|
|
118
|
+
description: "Zero-trust security — deny-by-default IAM, explicit allow rules.",
|
|
119
|
+
appliesWhen: "Project requires zero-trust network/IAM policies with deny-by-default.",
|
|
120
|
+
},
|
|
91
121
|
};
|
|
92
122
|
// ── Handlers ─────────────────────────────────────────────────────────
|
|
93
123
|
/**
|
|
@@ -152,4 +182,46 @@ export async function listHooksHandler(args) {
|
|
|
152
182
|
],
|
|
153
183
|
};
|
|
154
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* List all available skills (Claude Code custom commands), optionally filtered by tags.
|
|
187
|
+
*/
|
|
188
|
+
export async function listSkillsHandler(args) {
|
|
189
|
+
const templateSets = await loadAllTemplates();
|
|
190
|
+
const skills = [];
|
|
191
|
+
for (const [_tag, templateSet] of templateSets) {
|
|
192
|
+
if (args.tags && !args.tags.includes(templateSet.tag)) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (templateSet.skills) {
|
|
196
|
+
for (const skill of templateSet.skills) {
|
|
197
|
+
skills.push({
|
|
198
|
+
id: skill.id,
|
|
199
|
+
name: skill.name,
|
|
200
|
+
tag: templateSet.tag,
|
|
201
|
+
filename: skill.filename,
|
|
202
|
+
description: skill.description,
|
|
203
|
+
tier: skill.tier,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (skills.length === 0) {
|
|
209
|
+
return {
|
|
210
|
+
content: [
|
|
211
|
+
{ type: "text", text: "No skills found for the specified tags." },
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const formatted = skills
|
|
216
|
+
.map((s) => `- **${s.name}** [${s.tag}] ${s.tier ? `(${s.tier})` : ""}\n ${s.description}\n Command: \`/project:${s.filename.replace(".md", "")}\``)
|
|
217
|
+
.join("\n\n");
|
|
218
|
+
return {
|
|
219
|
+
content: [
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
text: `# Available Skills (${skills.length})\n\n${formatted}`,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
155
227
|
//# sourceMappingURL=list.js.map
|