@agiflowai/scaffold-mcp 1.2.0 → 1.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 +14 -0
- package/dist/{ListScaffoldingMethodsTool-DxdrPlcb.mjs → ListScaffoldingMethodsTool-dHaM4QXT.mjs} +6 -2
- package/dist/{ListScaffoldingMethodsTool-CYZtpU-W.cjs → ListScaffoldingMethodsTool-rX9Hxn2d.cjs} +6 -2
- package/dist/{claudeCode-DbKOy8W8.mjs → claudeCode-CyHppxA_.mjs} +12 -3
- package/dist/{claudeCode-g1eRidPR.cjs → claudeCode-DZnJyFQt.cjs} +12 -3
- package/dist/cli.cjs +16 -6
- package/dist/cli.mjs +18 -8
- package/dist/codex-7ry557jE.mjs +254 -0
- package/dist/codex-CfOJFx29.cjs +255 -0
- package/dist/{geminiCli-CcrZEqsz.mjs → geminiCli-CgajucCd.mjs} +10 -2
- package/dist/{geminiCli--s1Qy7ZP.cjs → geminiCli-wTHUG-A6.cjs} +10 -2
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +3 -3
- package/dist/shared-B0H-6AUG.cjs +187 -0
- package/dist/shared-BJjclypj.mjs +149 -0
- package/dist/{src-BG_X82dw.cjs → src-CRT1Er93.cjs} +3 -3
- package/dist/{src-DnVktdhD.mjs → src-CUQR93cQ.mjs} +3 -3
- package/dist/{tools-Dn5KgBUI.mjs → tools-BR1vQd_Y.mjs} +1 -1
- package/dist/{tools-COb9iBtt.cjs → tools-CV6GWs6f.cjs} +1 -1
- package/package.json +5 -5
- package/dist/shared-BVYIN3Is.mjs +0 -38
- package/dist/shared-QxPXh-L-.cjs +0 -52
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { TemplatesManagerService } from "@agiflowai/aicode-utils";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { minimatch } from "minimatch";
|
|
5
|
+
/**
|
|
6
|
+
* Returns true when an absolute write target matches any of the given exclude globs.
|
|
7
|
+
*
|
|
8
|
+
* Scaffold methods carry no target glob, so the hook cannot tell whether a method
|
|
9
|
+
* applies to a given path: once any method exists it denies every new-file write,
|
|
10
|
+
* which pushes agents to bypass the hook via Bash heredocs (skipping downstream
|
|
11
|
+
* review hooks). Exclude globs are the configured escape hatch — matching writes are
|
|
12
|
+
* allowed through directly. Globs come from two sources: workspace-wide
|
|
13
|
+
* (`scaffold-mcp.hook.excludeGlobs` in .toolkit/settings.yaml, see
|
|
14
|
+
* {@link getGlobalExcludeGlobs}) and per-template (`exclude` in scaffold.yaml).
|
|
15
|
+
*
|
|
16
|
+
* `dot: true` lets the globs traverse dot-directories (e.g. worktree paths) so a
|
|
17
|
+
* file nested under one is not misclassified.
|
|
18
|
+
*
|
|
19
|
+
* @param absPath - Absolute path of the new-file write target.
|
|
20
|
+
* @param globs - Glob patterns to match against; empty/undefined matches nothing.
|
|
21
|
+
* @returns True when `absPath` matches at least one glob.
|
|
22
|
+
*/
|
|
23
|
+
function matchesExcludeGlob(absPath, globs) {
|
|
24
|
+
if (!globs || globs.length === 0) return false;
|
|
25
|
+
return globs.some((glob) => minimatch(absPath, glob, { dot: true }));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Loads the workspace-wide scaffold-enforcement exclude globs from the toolkit
|
|
29
|
+
* config (`scaffold-mcp.hook.excludeGlobs` in .toolkit/settings.yaml).
|
|
30
|
+
*
|
|
31
|
+
* Fails open (returns an empty array) when the config is missing or unreadable so a
|
|
32
|
+
* broken config never blocks writes.
|
|
33
|
+
*
|
|
34
|
+
* @param cwd - Directory to resolve the workspace config from (walks up to the root).
|
|
35
|
+
* @returns The configured exclude globs, or an empty array when none are set.
|
|
36
|
+
*/
|
|
37
|
+
async function getGlobalExcludeGlobs(cwd) {
|
|
38
|
+
try {
|
|
39
|
+
const globs = (await TemplatesManagerService.readToolkitConfig(cwd))?.["scaffold-mcp"]?.hook?.excludeGlobs;
|
|
40
|
+
return Array.isArray(globs) ? globs : [];
|
|
41
|
+
} catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function resolveNewFileWriteTarget(cwd, toolName, filePath) {
|
|
46
|
+
if (!filePath || toolName.toLowerCase() !== "write") return null;
|
|
47
|
+
const absoluteFilePath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
48
|
+
if (!absoluteFilePath.startsWith(cwd + path.sep) && absoluteFilePath !== cwd) return null;
|
|
49
|
+
try {
|
|
50
|
+
await fs.access(absoluteFilePath);
|
|
51
|
+
return null;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return absoluteFilePath;
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parses a Codex `apply_patch` command body into the file paths it adds, updates,
|
|
59
|
+
* and deletes. Paths are returned verbatim (as written in the patch, i.e. relative
|
|
60
|
+
* to cwd). Pure and synchronous — performs no filesystem access.
|
|
61
|
+
*
|
|
62
|
+
* @param command - The `apply_patch` patch body (the tool_input.command string).
|
|
63
|
+
* @returns The added/updated/deleted path lists.
|
|
64
|
+
*/
|
|
65
|
+
function parseApplyPatchTargets(command) {
|
|
66
|
+
const added = [];
|
|
67
|
+
const updated = [];
|
|
68
|
+
const deleted = [];
|
|
69
|
+
for (const line of command.split("\n")) {
|
|
70
|
+
const add = line.match(/^\*\*\* Add File: (.+)$/);
|
|
71
|
+
if (add) {
|
|
72
|
+
added.push(add[1].trim());
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const update = line.match(/^\*\*\* Update File: (.+)$/);
|
|
76
|
+
if (update) {
|
|
77
|
+
updated.push(update[1].trim());
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const del = line.match(/^\*\*\* Delete File: (.+)$/);
|
|
81
|
+
if (del) deleted.push(del[1].trim());
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
added,
|
|
85
|
+
updated,
|
|
86
|
+
deleted
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Resolves the absolute, cwd-scoped paths of NEW files a Codex `apply_patch` tool
|
|
91
|
+
* call creates (its `*** Add File:` targets). Returns an empty array for any other
|
|
92
|
+
* tool or a missing command.
|
|
93
|
+
*
|
|
94
|
+
* Unlike {@link resolveNewFileWriteTarget} (the Claude/Gemini `Write` resolver), this
|
|
95
|
+
* performs no on-disk existence check: an `Add File` block is new-file creation by
|
|
96
|
+
* definition, and the patch fails downstream if the path already exists.
|
|
97
|
+
*
|
|
98
|
+
* @param cwd - Working directory the patch paths are relative to.
|
|
99
|
+
* @param toolName - The Codex tool name (only `apply_patch` is handled).
|
|
100
|
+
* @param command - The `apply_patch` patch body (tool_input.command).
|
|
101
|
+
* @returns Absolute paths of new files created under cwd.
|
|
102
|
+
*/
|
|
103
|
+
function resolveApplyPatchNewFileTargets(cwd, toolName, command) {
|
|
104
|
+
if (!command || toolName !== "apply_patch") return [];
|
|
105
|
+
const targets = [];
|
|
106
|
+
for (const filePath of parseApplyPatchTargets(command).added) {
|
|
107
|
+
const absoluteFilePath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
108
|
+
if (absoluteFilePath.startsWith(cwd + path.sep) || absoluteFilePath === cwd) targets.push(absoluteFilePath);
|
|
109
|
+
}
|
|
110
|
+
return targets;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Returns the file paths a Codex `apply_patch` call writes (adds or updates), as
|
|
114
|
+
* written in the patch. Used to correlate post-write edits with a scaffold's
|
|
115
|
+
* generated files. Returns an empty array for any other tool or a missing command.
|
|
116
|
+
*
|
|
117
|
+
* @param toolName - The Codex tool name (only `apply_patch` is handled).
|
|
118
|
+
* @param command - The `apply_patch` patch body (tool_input.command).
|
|
119
|
+
* @returns The added and updated paths (verbatim).
|
|
120
|
+
*/
|
|
121
|
+
function resolveApplyPatchEditedPaths(toolName, command) {
|
|
122
|
+
if (!command || toolName !== "apply_patch") return [];
|
|
123
|
+
const { added, updated } = parseApplyPatchTargets(command);
|
|
124
|
+
return [...added, ...updated];
|
|
125
|
+
}
|
|
126
|
+
function formatScaffoldMethodsHookMessage(methods, options) {
|
|
127
|
+
const maxMethods = options?.maxMethods ?? 5;
|
|
128
|
+
const requiredVarsMethodLimit = options?.requiredVarsMethodLimit ?? 2;
|
|
129
|
+
const maxRequiredVars = options?.maxRequiredVars ?? 3;
|
|
130
|
+
const visibleMethods = methods.slice(0, maxMethods);
|
|
131
|
+
const hiddenCount = Math.max(methods.length - visibleMethods.length, 0);
|
|
132
|
+
let message = "Before writing this new file, use `use-scaffold-method` if any of these fit:\n\n";
|
|
133
|
+
for (const [index, method] of visibleMethods.entries()) {
|
|
134
|
+
message += `- **${method.name}**: ${method.description || "No description available"}\n`;
|
|
135
|
+
if (options?.includeRequiredVars && index < requiredVarsMethodLimit) {
|
|
136
|
+
const requiredVars = method.variables_schema?.required ?? [];
|
|
137
|
+
if (requiredVars.length > 0) {
|
|
138
|
+
const visibleVars = requiredVars.slice(0, maxRequiredVars);
|
|
139
|
+
const moreCount = Math.max(requiredVars.length - visibleVars.length, 0);
|
|
140
|
+
const suffix = moreCount > 0 ? `, +${moreCount} more` : "";
|
|
141
|
+
message += ` Required: ${visibleVars.join(", ")}${suffix}\n`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (hiddenCount > 0) message += `\n...and ${hiddenCount} more methods. Call \`list-scaffolding-methods\` for the full list.\n`;
|
|
146
|
+
return message.trimEnd();
|
|
147
|
+
}
|
|
148
|
+
//#endregion
|
|
149
|
+
export { resolveApplyPatchNewFileTargets as a, resolveApplyPatchEditedPaths as i, getGlobalExcludeGlobs as n, resolveNewFileWriteTarget as o, matchesExcludeGlob as r, formatScaffoldMethodsHookMessage as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_ListScaffoldingMethodsTool = require("./ListScaffoldingMethodsTool-
|
|
2
|
-
const require_tools = require("./tools-
|
|
1
|
+
const require_ListScaffoldingMethodsTool = require("./ListScaffoldingMethodsTool-rX9Hxn2d.cjs");
|
|
2
|
+
const require_tools = require("./tools-CV6GWs6f.cjs");
|
|
3
3
|
let _agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
4
4
|
let _modelcontextprotocol_sdk_server_index_js = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
5
|
let _modelcontextprotocol_sdk_types_js = require("@modelcontextprotocol/sdk/types.js");
|
|
@@ -11,7 +11,7 @@ express = require_ListScaffoldingMethodsTool.__toESM(express, 1);
|
|
|
11
11
|
let node_crypto = require("node:crypto");
|
|
12
12
|
let _modelcontextprotocol_sdk_server_streamableHttp_js = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
13
13
|
//#region package.json
|
|
14
|
-
var version = "1.1
|
|
14
|
+
var version = "1.2.1";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/instructions/server.md?raw
|
|
17
17
|
var server_default = "Use this MCP server to {% if isMonolith %}create your monolith project and add features (pages, components, services, etc.){% else %}create new projects and add features (pages, components, services, etc.){% endif %}.\n\n## Workflow:\n{% if not isMonolith %}\n1. **Creating New Project**: Use `list-boilerplates` → `use-boilerplate`\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% else %}\n1. **Creating Project**: Use `use-boilerplate` (boilerplateName auto-detected from `.toolkit/settings.yaml`)\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% endif %}\n\n## AI Usage Guidelines:\n{% if not isMonolith %}\n- Always call `list-boilerplates` first when creating new projects to see available options\n{% endif %}\n- Always call `list-scaffolding-methods` first when adding features to understand what's available\n- Follow the exact variable schema provided - validation will fail if required fields are missing\n{% if not isMonolith %}\n- Use kebab-case for project names (e.g., \"my-new-app\")\n{% else %}\n- In monolith mode, parameters like `boilerplateName` and `templateName` are auto-detected from `.toolkit/settings.yaml`\n- You only need to provide `variables` when calling `use-boilerplate` or `use-scaffold-method`\n{% endif %}\n- The tools automatically handle file placement, imports, and code generation\n- Check the returned JSON schemas to understand required vs optional variables\n{% if adminEnabled %}\n\n## Admin Mode (Template Generation):\n\nWhen creating custom boilerplate templates for frameworks not yet supported:\n\n1. **Create Boilerplate Configuration**: Use `generate-boilerplate` to add a new boilerplate entry to a template's scaffold.yaml\n - Specify template name, boilerplate name, description, target folder, and variable schema\n - This creates the scaffold.yaml structure following the nextjs-15 pattern\n - Optional: Add detailed instruction about file purposes and design patterns\n\n2. **Create Feature Configuration**: Use `generate-feature-scaffold` to add a new feature entry to a template's scaffold.yaml\n - Specify template name, feature name, generator, description, and variable schema\n - This creates the scaffold.yaml structure for feature scaffolds (pages, components, etc.)\n - Optional: Add detailed instruction about file purposes and design patterns\n - Optional: Specify patterns to match existing files this feature works with\n\n3. **Create Template Files**: Use `generate-boilerplate-file` to create the actual template files\n - Create files referenced in the boilerplate's or feature's includes array\n - Use {{ variableName }} syntax for Liquid variable placeholders\n - Can copy from existing source files or provide content directly\n - Files automatically get .liquid extension\n\n4. **Test the Template**: Use `list-boilerplates`/`list-scaffolding-methods` and `use-boilerplate`/`use-scaffold-method` to verify your template works\n\nExample workflow for boilerplate:\n```\n1. generate-boilerplate { templateName: \"react-vite\", boilerplateName: \"scaffold-vite-app\", ... }\n2. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"package.json\", content: \"...\" }\n3. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"src/App.tsx\", content: \"...\" }\n4. list-boilerplates (verify it appears)\n5. use-boilerplate { boilerplateName: \"scaffold-vite-app\", variables: {...} }\n```\n\nExample workflow for feature:\n```\n1. generate-feature-scaffold { templateName: \"nextjs-15\", featureName: \"scaffold-nextjs-component\", generator: \"componentGenerator.ts\", ... }\n2. generate-boilerplate-file { templateName: \"nextjs-15\", filePath: \"src/components/Component.tsx\", content: \"...\" }\n3. list-scaffolding-methods (verify it appears)\n4. use-scaffold-method { scaffoldName: \"scaffold-nextjs-component\", variables: {...} }\n```\n{% endif %}\n";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as TemplateService, t as ListScaffoldingMethodsTool } from "./ListScaffoldingMethodsTool-
|
|
2
|
-
import { a as ListBoilerplatesTool, c as GenerateBoilerplateFileTool, i as UseBoilerplateTool, n as UseScaffoldMethodTool, o as GenerateFeatureScaffoldTool, s as GenerateBoilerplateTool, t as WriteToFileTool } from "./tools-
|
|
1
|
+
import { l as TemplateService, t as ListScaffoldingMethodsTool } from "./ListScaffoldingMethodsTool-dHaM4QXT.mjs";
|
|
2
|
+
import { a as ListBoilerplatesTool, c as GenerateBoilerplateFileTool, i as UseBoilerplateTool, n as UseScaffoldMethodTool, o as GenerateFeatureScaffoldTool, s as GenerateBoilerplateTool, t as WriteToFileTool } from "./tools-BR1vQd_Y.mjs";
|
|
3
3
|
import { TemplatesManagerService } from "@agiflowai/aicode-utils";
|
|
4
4
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5
5
|
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -10,7 +10,7 @@ import express from "express";
|
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
12
12
|
//#region package.json
|
|
13
|
-
var version = "1.1
|
|
13
|
+
var version = "1.2.1";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/instructions/server.md?raw
|
|
16
16
|
var server_default = "Use this MCP server to {% if isMonolith %}create your monolith project and add features (pages, components, services, etc.){% else %}create new projects and add features (pages, components, services, etc.){% endif %}.\n\n## Workflow:\n{% if not isMonolith %}\n1. **Creating New Project**: Use `list-boilerplates` → `use-boilerplate`\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% else %}\n1. **Creating Project**: Use `use-boilerplate` (boilerplateName auto-detected from `.toolkit/settings.yaml`)\n2. **Adding Features**: Use `list-scaffolding-methods` → `use-scaffold-method`\n{% endif %}\n\n## AI Usage Guidelines:\n{% if not isMonolith %}\n- Always call `list-boilerplates` first when creating new projects to see available options\n{% endif %}\n- Always call `list-scaffolding-methods` first when adding features to understand what's available\n- Follow the exact variable schema provided - validation will fail if required fields are missing\n{% if not isMonolith %}\n- Use kebab-case for project names (e.g., \"my-new-app\")\n{% else %}\n- In monolith mode, parameters like `boilerplateName` and `templateName` are auto-detected from `.toolkit/settings.yaml`\n- You only need to provide `variables` when calling `use-boilerplate` or `use-scaffold-method`\n{% endif %}\n- The tools automatically handle file placement, imports, and code generation\n- Check the returned JSON schemas to understand required vs optional variables\n{% if adminEnabled %}\n\n## Admin Mode (Template Generation):\n\nWhen creating custom boilerplate templates for frameworks not yet supported:\n\n1. **Create Boilerplate Configuration**: Use `generate-boilerplate` to add a new boilerplate entry to a template's scaffold.yaml\n - Specify template name, boilerplate name, description, target folder, and variable schema\n - This creates the scaffold.yaml structure following the nextjs-15 pattern\n - Optional: Add detailed instruction about file purposes and design patterns\n\n2. **Create Feature Configuration**: Use `generate-feature-scaffold` to add a new feature entry to a template's scaffold.yaml\n - Specify template name, feature name, generator, description, and variable schema\n - This creates the scaffold.yaml structure for feature scaffolds (pages, components, etc.)\n - Optional: Add detailed instruction about file purposes and design patterns\n - Optional: Specify patterns to match existing files this feature works with\n\n3. **Create Template Files**: Use `generate-boilerplate-file` to create the actual template files\n - Create files referenced in the boilerplate's or feature's includes array\n - Use {{ variableName }} syntax for Liquid variable placeholders\n - Can copy from existing source files or provide content directly\n - Files automatically get .liquid extension\n\n4. **Test the Template**: Use `list-boilerplates`/`list-scaffolding-methods` and `use-boilerplate`/`use-scaffold-method` to verify your template works\n\nExample workflow for boilerplate:\n```\n1. generate-boilerplate { templateName: \"react-vite\", boilerplateName: \"scaffold-vite-app\", ... }\n2. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"package.json\", content: \"...\" }\n3. generate-boilerplate-file { templateName: \"react-vite\", filePath: \"src/App.tsx\", content: \"...\" }\n4. list-boilerplates (verify it appears)\n5. use-boilerplate { boilerplateName: \"scaffold-vite-app\", variables: {...} }\n```\n\nExample workflow for feature:\n```\n1. generate-feature-scaffold { templateName: \"nextjs-15\", featureName: \"scaffold-nextjs-component\", generator: \"componentGenerator.ts\", ... }\n2. generate-boilerplate-file { templateName: \"nextjs-15\", filePath: \"src/components/Component.tsx\", content: \"...\" }\n3. list-scaffolding-methods (verify it appears)\n4. use-scaffold-method { scaffoldName: \"scaffold-nextjs-component\", variables: {...} }\n```\n{% endif %}\n";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as PaginationHelper, i as ScaffoldService, l as TemplateService, n as ScaffoldingMethodsService, o as ScaffoldConfigLoader, r as VariableReplacementService, s as FileSystemService } from "./ListScaffoldingMethodsTool-
|
|
1
|
+
import { c as PaginationHelper, i as ScaffoldService, l as TemplateService, n as ScaffoldingMethodsService, o as ScaffoldConfigLoader, r as VariableReplacementService, s as FileSystemService } from "./ListScaffoldingMethodsTool-dHaM4QXT.mjs";
|
|
2
2
|
import { ProjectConfigResolver, ensureDir, generateStableId, log, pathExists, pathExistsSync, readFile, readFileSync, readdir, statSync, writeFile } from "@agiflowai/aicode-utils";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_ListScaffoldingMethodsTool = require("./ListScaffoldingMethodsTool-
|
|
1
|
+
const require_ListScaffoldingMethodsTool = require("./ListScaffoldingMethodsTool-rX9Hxn2d.cjs");
|
|
2
2
|
let _agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
3
3
|
let zod = require("zod");
|
|
4
4
|
let node_path = require("node:path");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agiflowai/scaffold-mcp",
|
|
3
3
|
"description": "MCP server for scaffolding applications with boilerplate templates",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"author": "AgiflowIO",
|
|
7
7
|
"repository": {
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"pino": "10.3.1",
|
|
49
49
|
"pino-pretty": "13.1.3",
|
|
50
50
|
"zod": "4.3.6",
|
|
51
|
-
"@agiflowai/aicode-utils": "1.
|
|
52
|
-
"@agiflowai/
|
|
53
|
-
"@agiflowai/
|
|
54
|
-
"@agiflowai/coding-agent-bridge": "1.
|
|
51
|
+
"@agiflowai/aicode-utils": "1.3.0",
|
|
52
|
+
"@agiflowai/hooks-adapter": "0.1.2",
|
|
53
|
+
"@agiflowai/architect-mcp": "1.3.0",
|
|
54
|
+
"@agiflowai/coding-agent-bridge": "1.3.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/express": "5.0.6",
|
package/dist/shared-BVYIN3Is.mjs
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
async function resolveNewFileWriteTarget(cwd, toolName, filePath) {
|
|
4
|
-
if (!filePath || toolName.toLowerCase() !== "write") return null;
|
|
5
|
-
const absoluteFilePath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
|
|
6
|
-
if (!absoluteFilePath.startsWith(cwd + path.sep) && absoluteFilePath !== cwd) return null;
|
|
7
|
-
try {
|
|
8
|
-
await fs.access(absoluteFilePath);
|
|
9
|
-
return null;
|
|
10
|
-
} catch (error) {
|
|
11
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return absoluteFilePath;
|
|
12
|
-
throw error;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function formatScaffoldMethodsHookMessage(methods, options) {
|
|
16
|
-
const maxMethods = options?.maxMethods ?? 5;
|
|
17
|
-
const requiredVarsMethodLimit = options?.requiredVarsMethodLimit ?? 2;
|
|
18
|
-
const maxRequiredVars = options?.maxRequiredVars ?? 3;
|
|
19
|
-
const visibleMethods = methods.slice(0, maxMethods);
|
|
20
|
-
const hiddenCount = Math.max(methods.length - visibleMethods.length, 0);
|
|
21
|
-
let message = "Before writing this new file, use `use-scaffold-method` if any of these fit:\n\n";
|
|
22
|
-
for (const [index, method] of visibleMethods.entries()) {
|
|
23
|
-
message += `- **${method.name}**: ${method.description || "No description available"}\n`;
|
|
24
|
-
if (options?.includeRequiredVars && index < requiredVarsMethodLimit) {
|
|
25
|
-
const requiredVars = method.variables_schema?.required ?? [];
|
|
26
|
-
if (requiredVars.length > 0) {
|
|
27
|
-
const visibleVars = requiredVars.slice(0, maxRequiredVars);
|
|
28
|
-
const moreCount = Math.max(requiredVars.length - visibleVars.length, 0);
|
|
29
|
-
const suffix = moreCount > 0 ? `, +${moreCount} more` : "";
|
|
30
|
-
message += ` Required: ${visibleVars.join(", ")}${suffix}\n`;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (hiddenCount > 0) message += `\n...and ${hiddenCount} more methods. Call \`list-scaffolding-methods\` for the full list.\n`;
|
|
35
|
-
return message.trimEnd();
|
|
36
|
-
}
|
|
37
|
-
//#endregion
|
|
38
|
-
export { resolveNewFileWriteTarget as n, formatScaffoldMethodsHookMessage as t };
|
package/dist/shared-QxPXh-L-.cjs
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const require_ListScaffoldingMethodsTool = require("./ListScaffoldingMethodsTool-CYZtpU-W.cjs");
|
|
2
|
-
let node_path = require("node:path");
|
|
3
|
-
node_path = require_ListScaffoldingMethodsTool.__toESM(node_path, 1);
|
|
4
|
-
let node_fs_promises = require("node:fs/promises");
|
|
5
|
-
node_fs_promises = require_ListScaffoldingMethodsTool.__toESM(node_fs_promises, 1);
|
|
6
|
-
async function resolveNewFileWriteTarget(cwd, toolName, filePath) {
|
|
7
|
-
if (!filePath || toolName.toLowerCase() !== "write") return null;
|
|
8
|
-
const absoluteFilePath = node_path.default.isAbsolute(filePath) ? filePath : node_path.default.join(cwd, filePath);
|
|
9
|
-
if (!absoluteFilePath.startsWith(cwd + node_path.default.sep) && absoluteFilePath !== cwd) return null;
|
|
10
|
-
try {
|
|
11
|
-
await node_fs_promises.default.access(absoluteFilePath);
|
|
12
|
-
return null;
|
|
13
|
-
} catch (error) {
|
|
14
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return absoluteFilePath;
|
|
15
|
-
throw error;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function formatScaffoldMethodsHookMessage(methods, options) {
|
|
19
|
-
const maxMethods = options?.maxMethods ?? 5;
|
|
20
|
-
const requiredVarsMethodLimit = options?.requiredVarsMethodLimit ?? 2;
|
|
21
|
-
const maxRequiredVars = options?.maxRequiredVars ?? 3;
|
|
22
|
-
const visibleMethods = methods.slice(0, maxMethods);
|
|
23
|
-
const hiddenCount = Math.max(methods.length - visibleMethods.length, 0);
|
|
24
|
-
let message = "Before writing this new file, use `use-scaffold-method` if any of these fit:\n\n";
|
|
25
|
-
for (const [index, method] of visibleMethods.entries()) {
|
|
26
|
-
message += `- **${method.name}**: ${method.description || "No description available"}\n`;
|
|
27
|
-
if (options?.includeRequiredVars && index < requiredVarsMethodLimit) {
|
|
28
|
-
const requiredVars = method.variables_schema?.required ?? [];
|
|
29
|
-
if (requiredVars.length > 0) {
|
|
30
|
-
const visibleVars = requiredVars.slice(0, maxRequiredVars);
|
|
31
|
-
const moreCount = Math.max(requiredVars.length - visibleVars.length, 0);
|
|
32
|
-
const suffix = moreCount > 0 ? `, +${moreCount} more` : "";
|
|
33
|
-
message += ` Required: ${visibleVars.join(", ")}${suffix}\n`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (hiddenCount > 0) message += `\n...and ${hiddenCount} more methods. Call \`list-scaffolding-methods\` for the full list.\n`;
|
|
38
|
-
return message.trimEnd();
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
Object.defineProperty(exports, "formatScaffoldMethodsHookMessage", {
|
|
42
|
-
enumerable: true,
|
|
43
|
-
get: function() {
|
|
44
|
-
return formatScaffoldMethodsHookMessage;
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
Object.defineProperty(exports, "resolveNewFileWriteTarget", {
|
|
48
|
-
enumerable: true,
|
|
49
|
-
get: function() {
|
|
50
|
-
return resolveNewFileWriteTarget;
|
|
51
|
-
}
|
|
52
|
-
});
|