@agiflowai/aicode-utils 1.0.16 → 1.0.18
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/dist/index.cjs +22 -0
- package/dist/index.d.cts +44 -1
- package/dist/index.d.mts +44 -1
- package/dist/index.mjs +78 -57
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -783,6 +783,27 @@ var ScaffoldProcessingService = class {
|
|
|
783
783
|
}
|
|
784
784
|
};
|
|
785
785
|
|
|
786
|
+
//#endregion
|
|
787
|
+
//#region src/utils/fallbacks.ts
|
|
788
|
+
function resolveFallbackConfig(config) {
|
|
789
|
+
if (!config) return {};
|
|
790
|
+
const tool = ("fallbackTool" in config ? config.fallbackTool : void 0) ?? ("fallback-tool" in config ? config["fallback-tool"] : void 0);
|
|
791
|
+
const fallbackConfig = ("fallbackToolConfig" in config ? config.fallbackToolConfig : void 0) ?? ("fallback-tool-config" in config ? config["fallback-tool-config"] : void 0);
|
|
792
|
+
if (tool) return {
|
|
793
|
+
tool,
|
|
794
|
+
config: fallbackConfig
|
|
795
|
+
};
|
|
796
|
+
const firstValidFallback = config.fallbacks?.find((entry) => isFallbackConfigEntry(entry));
|
|
797
|
+
if (!firstValidFallback) return {};
|
|
798
|
+
return {
|
|
799
|
+
tool: firstValidFallback.tool,
|
|
800
|
+
config: firstValidFallback.config
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function isFallbackConfigEntry(entry) {
|
|
804
|
+
return Boolean(entry?.tool && typeof entry.tool === "string");
|
|
805
|
+
}
|
|
806
|
+
|
|
786
807
|
//#endregion
|
|
787
808
|
//#region src/utils/generateStableId.ts
|
|
788
809
|
/**
|
|
@@ -1307,6 +1328,7 @@ exports.readJson = readJson;
|
|
|
1307
1328
|
exports.readJsonSync = readJsonSync;
|
|
1308
1329
|
exports.readdir = readdir;
|
|
1309
1330
|
exports.remove = remove;
|
|
1331
|
+
exports.resolveFallbackConfig = resolveFallbackConfig;
|
|
1310
1332
|
exports.sections = sections;
|
|
1311
1333
|
exports.stat = stat;
|
|
1312
1334
|
exports.statSync = node_fs.statSync;
|
package/dist/index.d.cts
CHANGED
|
@@ -46,6 +46,15 @@ interface NxProjectJson {
|
|
|
46
46
|
//#endregion
|
|
47
47
|
//#region src/types/index.d.ts
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Ordered fallback LLM entry used in toolkit settings.
|
|
51
|
+
*/
|
|
52
|
+
interface FallbackConfigEntry {
|
|
53
|
+
/** Fallback LLM tool identifier. */
|
|
54
|
+
tool: string;
|
|
55
|
+
/** Config object forwarded when this fallback tool is selected. */
|
|
56
|
+
config?: Record<string, unknown>;
|
|
57
|
+
}
|
|
49
58
|
/**
|
|
50
59
|
* Configuration for the scaffold-mcp mcp-serve command.
|
|
51
60
|
* Keys map 1-to-1 with CLI flags (camelCase).
|
|
@@ -65,6 +74,8 @@ interface McpServeConfig {
|
|
|
65
74
|
fallbackTool?: string;
|
|
66
75
|
/** Config passed to the fallback LLM tool. */
|
|
67
76
|
fallbackToolConfig?: Record<string, unknown>;
|
|
77
|
+
/** Ordered fallback LLM chain consulted when fallbackTool is not set. */
|
|
78
|
+
fallbacks?: FallbackConfigEntry[];
|
|
68
79
|
/** Extra CLI args merged into the mcp-serve command (key → --key value). */
|
|
69
80
|
args?: Record<string, string | boolean | number>;
|
|
70
81
|
}
|
|
@@ -81,6 +92,10 @@ interface HookMethodConfig {
|
|
|
81
92
|
'fallback-tool'?: string;
|
|
82
93
|
/** Config object forwarded to the fallback LLM tool. */
|
|
83
94
|
'fallback-tool-config'?: Record<string, unknown>;
|
|
95
|
+
/** Ordered fallback LLM chain consulted when fallback-tool is not set. */
|
|
96
|
+
fallbacks?: FallbackConfigEntry[];
|
|
97
|
+
/** Optional Claude Code tool matcher written to .claude/settings.json. */
|
|
98
|
+
matcher?: string;
|
|
84
99
|
/** Extra CLI args appended to the generated hook command (key → --key value). */
|
|
85
100
|
args?: Record<string, string | boolean | number>;
|
|
86
101
|
}
|
|
@@ -134,6 +149,8 @@ interface ArchitectMcpServeConfig {
|
|
|
134
149
|
fallbackTool?: string;
|
|
135
150
|
/** Config passed to the fallback LLM tool. */
|
|
136
151
|
fallbackToolConfig?: Record<string, unknown>;
|
|
152
|
+
/** Ordered fallback LLM chain consulted when fallbackTool is not set. */
|
|
153
|
+
fallbacks?: FallbackConfigEntry[];
|
|
137
154
|
/** LLM tool used specifically for get-file-design-pattern analysis. */
|
|
138
155
|
designPatternTool?: string;
|
|
139
156
|
/** Config passed to the design-pattern LLM tool. */
|
|
@@ -154,6 +171,14 @@ interface ArchitectHookMethodConfig {
|
|
|
154
171
|
'llm-tool'?: string;
|
|
155
172
|
/** Config object forwarded to the LLM tool. */
|
|
156
173
|
'tool-config'?: Record<string, unknown>;
|
|
174
|
+
/** Fallback LLM tool used when llm-tool is not set. */
|
|
175
|
+
'fallback-tool'?: string;
|
|
176
|
+
/** Config object forwarded to the fallback LLM tool. */
|
|
177
|
+
'fallback-tool-config'?: Record<string, unknown>;
|
|
178
|
+
/** Ordered fallback LLM chain consulted when fallback-tool is not set. */
|
|
179
|
+
fallbacks?: FallbackConfigEntry[];
|
|
180
|
+
/** Optional Claude Code tool matcher written to .claude/settings.json. */
|
|
181
|
+
matcher?: string;
|
|
157
182
|
/** Extra CLI args appended to the generated hook command (key → --key value). */
|
|
158
183
|
args?: Record<string, string | boolean | number>;
|
|
159
184
|
}
|
|
@@ -653,6 +678,24 @@ declare const readdir: typeof fs.readdir;
|
|
|
653
678
|
declare const mkdir: typeof fs.mkdir;
|
|
654
679
|
declare const stat: typeof fs.stat;
|
|
655
680
|
//#endregion
|
|
681
|
+
//#region src/utils/fallbacks.d.ts
|
|
682
|
+
interface SingleFallbackShape {
|
|
683
|
+
fallbackTool?: string;
|
|
684
|
+
fallbackToolConfig?: Record<string, unknown>;
|
|
685
|
+
}
|
|
686
|
+
interface HookFallbackShape {
|
|
687
|
+
'fallback-tool'?: string;
|
|
688
|
+
'fallback-tool-config'?: Record<string, unknown>;
|
|
689
|
+
}
|
|
690
|
+
interface FallbackListShape {
|
|
691
|
+
fallbacks?: FallbackConfigEntry[];
|
|
692
|
+
}
|
|
693
|
+
interface ResolvedFallbackConfig {
|
|
694
|
+
tool?: string;
|
|
695
|
+
config?: Record<string, unknown>;
|
|
696
|
+
}
|
|
697
|
+
declare function resolveFallbackConfig(config?: (SingleFallbackShape | HookFallbackShape) & FallbackListShape): ResolvedFallbackConfig;
|
|
698
|
+
//#endregion
|
|
656
699
|
//#region src/utils/generateStableId.d.ts
|
|
657
700
|
/**
|
|
658
701
|
* Generate a stable, random ID string
|
|
@@ -956,4 +999,4 @@ interface ProjectTypeDetectionResult {
|
|
|
956
999
|
*/
|
|
957
1000
|
declare function detectProjectType(workspaceRoot: string): Promise<ProjectTypeDetectionResult>;
|
|
958
1001
|
//#endregion
|
|
959
|
-
export { ArchitectHookAgentConfig, ArchitectHookConfig, ArchitectHookMethodConfig, ArchitectMcpConfig, ArchitectMcpServeConfig, ConfigSource, FileStat, GeneratorContext, GeneratorFunction, GitHubDirectoryEntry, HookAgentConfig, HookConfig, HookMethodConfig, IFileSystemService, IVariableReplacementService, McpServeConfig, type NxProjectJson, ParsedGitHubUrl, ParsedInclude, ProjectConfig, ProjectConfigResolver, type ProjectConfigResult, ProjectFinderService, ProjectType, ScaffoldMcpConfig, ScaffoldProcessingService, ScaffoldResult, TemplatesManagerService, ToolkitConfig, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, sections, stat, statSync, writeFile, writeFileSync };
|
|
1002
|
+
export { ArchitectHookAgentConfig, ArchitectHookConfig, ArchitectHookMethodConfig, ArchitectMcpConfig, ArchitectMcpServeConfig, ConfigSource, FallbackConfigEntry, FileStat, GeneratorContext, GeneratorFunction, GitHubDirectoryEntry, HookAgentConfig, HookConfig, HookMethodConfig, IFileSystemService, IVariableReplacementService, McpServeConfig, type NxProjectJson, ParsedGitHubUrl, ParsedInclude, ProjectConfig, ProjectConfigResolver, type ProjectConfigResult, ProjectFinderService, ProjectType, ResolvedFallbackConfig, ScaffoldMcpConfig, ScaffoldProcessingService, ScaffoldResult, TemplatesManagerService, ToolkitConfig, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, resolveFallbackConfig, sections, stat, statSync, writeFile, writeFileSync };
|
package/dist/index.d.mts
CHANGED
|
@@ -46,6 +46,15 @@ interface NxProjectJson {
|
|
|
46
46
|
//#endregion
|
|
47
47
|
//#region src/types/index.d.ts
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Ordered fallback LLM entry used in toolkit settings.
|
|
51
|
+
*/
|
|
52
|
+
interface FallbackConfigEntry {
|
|
53
|
+
/** Fallback LLM tool identifier. */
|
|
54
|
+
tool: string;
|
|
55
|
+
/** Config object forwarded when this fallback tool is selected. */
|
|
56
|
+
config?: Record<string, unknown>;
|
|
57
|
+
}
|
|
49
58
|
/**
|
|
50
59
|
* Configuration for the scaffold-mcp mcp-serve command.
|
|
51
60
|
* Keys map 1-to-1 with CLI flags (camelCase).
|
|
@@ -65,6 +74,8 @@ interface McpServeConfig {
|
|
|
65
74
|
fallbackTool?: string;
|
|
66
75
|
/** Config passed to the fallback LLM tool. */
|
|
67
76
|
fallbackToolConfig?: Record<string, unknown>;
|
|
77
|
+
/** Ordered fallback LLM chain consulted when fallbackTool is not set. */
|
|
78
|
+
fallbacks?: FallbackConfigEntry[];
|
|
68
79
|
/** Extra CLI args merged into the mcp-serve command (key → --key value). */
|
|
69
80
|
args?: Record<string, string | boolean | number>;
|
|
70
81
|
}
|
|
@@ -81,6 +92,10 @@ interface HookMethodConfig {
|
|
|
81
92
|
'fallback-tool'?: string;
|
|
82
93
|
/** Config object forwarded to the fallback LLM tool. */
|
|
83
94
|
'fallback-tool-config'?: Record<string, unknown>;
|
|
95
|
+
/** Ordered fallback LLM chain consulted when fallback-tool is not set. */
|
|
96
|
+
fallbacks?: FallbackConfigEntry[];
|
|
97
|
+
/** Optional Claude Code tool matcher written to .claude/settings.json. */
|
|
98
|
+
matcher?: string;
|
|
84
99
|
/** Extra CLI args appended to the generated hook command (key → --key value). */
|
|
85
100
|
args?: Record<string, string | boolean | number>;
|
|
86
101
|
}
|
|
@@ -134,6 +149,8 @@ interface ArchitectMcpServeConfig {
|
|
|
134
149
|
fallbackTool?: string;
|
|
135
150
|
/** Config passed to the fallback LLM tool. */
|
|
136
151
|
fallbackToolConfig?: Record<string, unknown>;
|
|
152
|
+
/** Ordered fallback LLM chain consulted when fallbackTool is not set. */
|
|
153
|
+
fallbacks?: FallbackConfigEntry[];
|
|
137
154
|
/** LLM tool used specifically for get-file-design-pattern analysis. */
|
|
138
155
|
designPatternTool?: string;
|
|
139
156
|
/** Config passed to the design-pattern LLM tool. */
|
|
@@ -154,6 +171,14 @@ interface ArchitectHookMethodConfig {
|
|
|
154
171
|
'llm-tool'?: string;
|
|
155
172
|
/** Config object forwarded to the LLM tool. */
|
|
156
173
|
'tool-config'?: Record<string, unknown>;
|
|
174
|
+
/** Fallback LLM tool used when llm-tool is not set. */
|
|
175
|
+
'fallback-tool'?: string;
|
|
176
|
+
/** Config object forwarded to the fallback LLM tool. */
|
|
177
|
+
'fallback-tool-config'?: Record<string, unknown>;
|
|
178
|
+
/** Ordered fallback LLM chain consulted when fallback-tool is not set. */
|
|
179
|
+
fallbacks?: FallbackConfigEntry[];
|
|
180
|
+
/** Optional Claude Code tool matcher written to .claude/settings.json. */
|
|
181
|
+
matcher?: string;
|
|
157
182
|
/** Extra CLI args appended to the generated hook command (key → --key value). */
|
|
158
183
|
args?: Record<string, string | boolean | number>;
|
|
159
184
|
}
|
|
@@ -653,6 +678,24 @@ declare const readdir: typeof fs.readdir;
|
|
|
653
678
|
declare const mkdir: typeof fs.mkdir;
|
|
654
679
|
declare const stat: typeof fs.stat;
|
|
655
680
|
//#endregion
|
|
681
|
+
//#region src/utils/fallbacks.d.ts
|
|
682
|
+
interface SingleFallbackShape {
|
|
683
|
+
fallbackTool?: string;
|
|
684
|
+
fallbackToolConfig?: Record<string, unknown>;
|
|
685
|
+
}
|
|
686
|
+
interface HookFallbackShape {
|
|
687
|
+
'fallback-tool'?: string;
|
|
688
|
+
'fallback-tool-config'?: Record<string, unknown>;
|
|
689
|
+
}
|
|
690
|
+
interface FallbackListShape {
|
|
691
|
+
fallbacks?: FallbackConfigEntry[];
|
|
692
|
+
}
|
|
693
|
+
interface ResolvedFallbackConfig {
|
|
694
|
+
tool?: string;
|
|
695
|
+
config?: Record<string, unknown>;
|
|
696
|
+
}
|
|
697
|
+
declare function resolveFallbackConfig(config?: (SingleFallbackShape | HookFallbackShape) & FallbackListShape): ResolvedFallbackConfig;
|
|
698
|
+
//#endregion
|
|
656
699
|
//#region src/utils/generateStableId.d.ts
|
|
657
700
|
/**
|
|
658
701
|
* Generate a stable, random ID string
|
|
@@ -956,4 +999,4 @@ interface ProjectTypeDetectionResult {
|
|
|
956
999
|
*/
|
|
957
1000
|
declare function detectProjectType(workspaceRoot: string): Promise<ProjectTypeDetectionResult>;
|
|
958
1001
|
//#endregion
|
|
959
|
-
export { ArchitectHookAgentConfig, ArchitectHookConfig, ArchitectHookMethodConfig, ArchitectMcpConfig, ArchitectMcpServeConfig, ConfigSource, FileStat, GeneratorContext, GeneratorFunction, type GitHubDirectoryEntry, HookAgentConfig, HookConfig, HookMethodConfig, IFileSystemService, IVariableReplacementService, McpServeConfig, type NxProjectJson, type ParsedGitHubUrl, ParsedInclude, ProjectConfig, ProjectConfigResolver, type ProjectConfigResult, ProjectFinderService, ProjectType, ScaffoldMcpConfig, ScaffoldProcessingService, ScaffoldResult, TemplatesManagerService, ToolkitConfig, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, sections, stat, statSync, writeFile, writeFileSync };
|
|
1002
|
+
export { ArchitectHookAgentConfig, ArchitectHookConfig, ArchitectHookMethodConfig, ArchitectMcpConfig, ArchitectMcpServeConfig, ConfigSource, FallbackConfigEntry, FileStat, GeneratorContext, GeneratorFunction, type GitHubDirectoryEntry, HookAgentConfig, HookConfig, HookMethodConfig, IFileSystemService, IVariableReplacementService, McpServeConfig, type NxProjectJson, type ParsedGitHubUrl, ParsedInclude, ProjectConfig, ProjectConfigResolver, type ProjectConfigResult, ProjectFinderService, ProjectType, type ResolvedFallbackConfig, ScaffoldMcpConfig, ScaffoldProcessingService, ScaffoldResult, TemplatesManagerService, ToolkitConfig, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, resolveFallbackConfig, sections, stat, statSync, writeFile, writeFileSync };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import * as path
|
|
3
|
-
import
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import nodePath from "node:path";
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
5
5
|
import { accessSync, mkdirSync, readFileSync, readFileSync as readFileSync$1, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import * as os from "node:os";
|
|
@@ -84,7 +84,7 @@ async function copy(src, dest) {
|
|
|
84
84
|
* Move a file or directory
|
|
85
85
|
*/
|
|
86
86
|
async function move(src, dest) {
|
|
87
|
-
await ensureDir(
|
|
87
|
+
await ensureDir(nodePath.dirname(dest));
|
|
88
88
|
await fs.rename(src, dest);
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
@@ -120,12 +120,12 @@ const cp = fs.cp;
|
|
|
120
120
|
|
|
121
121
|
//#endregion
|
|
122
122
|
//#region src/utils/logger.ts
|
|
123
|
-
const logsDir = path
|
|
123
|
+
const logsDir = path.join(os.tmpdir(), "scaffold-mcp-logs");
|
|
124
124
|
const logger = pino({
|
|
125
125
|
level: process.env.LOG_LEVEL || "debug",
|
|
126
126
|
timestamp: pino.stdTimeFunctions.isoTime
|
|
127
127
|
}, pino.destination({
|
|
128
|
-
dest: path
|
|
128
|
+
dest: path.join(logsDir, "scaffold-mcp.log"),
|
|
129
129
|
mkdir: true,
|
|
130
130
|
sync: true
|
|
131
131
|
}));
|
|
@@ -208,11 +208,11 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
208
208
|
const workspaceRoot = await TemplatesManagerService.findWorkspaceRoot(startPath);
|
|
209
209
|
const config = await TemplatesManagerService.readToolkitConfig(startPath);
|
|
210
210
|
if (config?.templatesPath) {
|
|
211
|
-
const templatesPath$1 =
|
|
211
|
+
const templatesPath$1 = nodePath.isAbsolute(config.templatesPath) ? config.templatesPath : nodePath.join(workspaceRoot, config.templatesPath);
|
|
212
212
|
if (await pathExists(templatesPath$1)) return templatesPath$1;
|
|
213
213
|
return null;
|
|
214
214
|
}
|
|
215
|
-
const templatesPath =
|
|
215
|
+
const templatesPath = nodePath.join(workspaceRoot, TemplatesManagerService.TEMPLATES_FOLDER);
|
|
216
216
|
if (await pathExists(templatesPath)) return templatesPath;
|
|
217
217
|
return null;
|
|
218
218
|
}
|
|
@@ -220,12 +220,12 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
220
220
|
* Find the workspace root by searching upwards for .git folder
|
|
221
221
|
*/
|
|
222
222
|
static async findWorkspaceRoot(startPath) {
|
|
223
|
-
let currentPath =
|
|
224
|
-
const rootPath =
|
|
223
|
+
let currentPath = nodePath.resolve(startPath);
|
|
224
|
+
const rootPath = nodePath.parse(currentPath).root;
|
|
225
225
|
while (true) {
|
|
226
|
-
if (await pathExists(
|
|
226
|
+
if (await pathExists(nodePath.join(currentPath, ".git"))) return currentPath;
|
|
227
227
|
if (currentPath === rootPath) return process.cwd();
|
|
228
|
-
currentPath =
|
|
228
|
+
currentPath = nodePath.dirname(currentPath);
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
/**
|
|
@@ -239,11 +239,11 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
239
239
|
const workspaceRoot = TemplatesManagerService.findWorkspaceRootSync(startPath);
|
|
240
240
|
const config = TemplatesManagerService.readToolkitConfigSync(startPath);
|
|
241
241
|
if (config?.templatesPath) {
|
|
242
|
-
const templatesPath$1 =
|
|
242
|
+
const templatesPath$1 = nodePath.isAbsolute(config.templatesPath) ? config.templatesPath : nodePath.join(workspaceRoot, config.templatesPath);
|
|
243
243
|
if (pathExistsSync(templatesPath$1)) return templatesPath$1;
|
|
244
244
|
return null;
|
|
245
245
|
}
|
|
246
|
-
const templatesPath =
|
|
246
|
+
const templatesPath = nodePath.join(workspaceRoot, TemplatesManagerService.TEMPLATES_FOLDER);
|
|
247
247
|
if (pathExistsSync(templatesPath)) return templatesPath;
|
|
248
248
|
return null;
|
|
249
249
|
}
|
|
@@ -251,12 +251,12 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
251
251
|
* Find the workspace root synchronously by searching upwards for .git folder
|
|
252
252
|
*/
|
|
253
253
|
static findWorkspaceRootSync(startPath) {
|
|
254
|
-
let currentPath =
|
|
255
|
-
const rootPath =
|
|
254
|
+
let currentPath = nodePath.resolve(startPath);
|
|
255
|
+
const rootPath = nodePath.parse(currentPath).root;
|
|
256
256
|
while (true) {
|
|
257
|
-
if (pathExistsSync(
|
|
257
|
+
if (pathExistsSync(nodePath.join(currentPath, ".git"))) return currentPath;
|
|
258
258
|
if (currentPath === rootPath) return process.cwd();
|
|
259
|
-
currentPath =
|
|
259
|
+
currentPath = nodePath.dirname(currentPath);
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
/**
|
|
@@ -295,9 +295,9 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
295
295
|
static async readToolkitConfig(startPath = process.cwd()) {
|
|
296
296
|
const workspaceRoot = await TemplatesManagerService.findWorkspaceRoot(startPath);
|
|
297
297
|
const yaml$1 = await import("js-yaml");
|
|
298
|
-
const toolkitFolder =
|
|
299
|
-
const settingsPath =
|
|
300
|
-
const settingsLocalPath =
|
|
298
|
+
const toolkitFolder = nodePath.join(workspaceRoot, TemplatesManagerService.TOOLKIT_FOLDER);
|
|
299
|
+
const settingsPath = nodePath.join(toolkitFolder, TemplatesManagerService.SETTINGS_FILE);
|
|
300
|
+
const settingsLocalPath = nodePath.join(toolkitFolder, TemplatesManagerService.SETTINGS_LOCAL_FILE);
|
|
301
301
|
if (await pathExists(settingsPath)) {
|
|
302
302
|
const baseContent = await fs.readFile(settingsPath, "utf-8");
|
|
303
303
|
const base = yaml$1.load(baseContent);
|
|
@@ -308,7 +308,7 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
308
308
|
}
|
|
309
309
|
return base;
|
|
310
310
|
}
|
|
311
|
-
const legacyConfigPath =
|
|
311
|
+
const legacyConfigPath = nodePath.join(workspaceRoot, TemplatesManagerService.TOOLKIT_CONFIG_FILE);
|
|
312
312
|
if (!await pathExists(legacyConfigPath)) return null;
|
|
313
313
|
const content = await fs.readFile(legacyConfigPath, "utf-8");
|
|
314
314
|
return yaml$1.load(content);
|
|
@@ -327,9 +327,9 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
327
327
|
static readToolkitConfigSync(startPath = process.cwd()) {
|
|
328
328
|
const workspaceRoot = TemplatesManagerService.findWorkspaceRootSync(startPath);
|
|
329
329
|
const yaml$1 = __require("js-yaml");
|
|
330
|
-
const toolkitFolder =
|
|
331
|
-
const settingsPath =
|
|
332
|
-
const settingsLocalPath =
|
|
330
|
+
const toolkitFolder = nodePath.join(workspaceRoot, TemplatesManagerService.TOOLKIT_FOLDER);
|
|
331
|
+
const settingsPath = nodePath.join(toolkitFolder, TemplatesManagerService.SETTINGS_FILE);
|
|
332
|
+
const settingsLocalPath = nodePath.join(toolkitFolder, TemplatesManagerService.SETTINGS_LOCAL_FILE);
|
|
333
333
|
if (pathExistsSync(settingsPath)) {
|
|
334
334
|
const base = yaml$1.load(readFileSync$1(settingsPath, "utf-8"));
|
|
335
335
|
if (pathExistsSync(settingsLocalPath)) {
|
|
@@ -338,7 +338,7 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
338
338
|
}
|
|
339
339
|
return base;
|
|
340
340
|
}
|
|
341
|
-
const legacyConfigPath =
|
|
341
|
+
const legacyConfigPath = nodePath.join(workspaceRoot, TemplatesManagerService.TOOLKIT_CONFIG_FILE);
|
|
342
342
|
if (!pathExistsSync(legacyConfigPath)) return null;
|
|
343
343
|
return yaml$1.load(readFileSync$1(legacyConfigPath, "utf-8"));
|
|
344
344
|
}
|
|
@@ -351,8 +351,8 @@ var TemplatesManagerService = class TemplatesManagerService {
|
|
|
351
351
|
*/
|
|
352
352
|
static async writeToolkitConfig(config, startPath = process.cwd()) {
|
|
353
353
|
const workspaceRoot = await TemplatesManagerService.findWorkspaceRoot(startPath);
|
|
354
|
-
const toolkitFolder =
|
|
355
|
-
const settingsPath =
|
|
354
|
+
const toolkitFolder = nodePath.join(workspaceRoot, TemplatesManagerService.TOOLKIT_FOLDER);
|
|
355
|
+
const settingsPath = nodePath.join(toolkitFolder, TemplatesManagerService.SETTINGS_FILE);
|
|
356
356
|
await fs.mkdir(toolkitFolder, { recursive: true });
|
|
357
357
|
const content = (await import("js-yaml")).dump(config, { indent: 2 });
|
|
358
358
|
await fs.writeFile(settingsPath, content, "utf-8");
|
|
@@ -424,13 +424,13 @@ var ProjectConfigResolver = class ProjectConfigResolver {
|
|
|
424
424
|
*/
|
|
425
425
|
static async resolveProjectConfig(projectPath, explicitTemplate) {
|
|
426
426
|
try {
|
|
427
|
-
const absolutePath =
|
|
427
|
+
const absolutePath = nodePath.resolve(projectPath);
|
|
428
428
|
if (explicitTemplate) return {
|
|
429
429
|
type: ProjectType.MONOLITH,
|
|
430
430
|
sourceTemplate: explicitTemplate,
|
|
431
431
|
configSource: ConfigSource.TOOLKIT_YAML
|
|
432
432
|
};
|
|
433
|
-
const projectJsonPath =
|
|
433
|
+
const projectJsonPath = nodePath.join(absolutePath, "project.json");
|
|
434
434
|
if (await pathExists(projectJsonPath)) {
|
|
435
435
|
const projectJson = await readJson(projectJsonPath);
|
|
436
436
|
if (projectJson.sourceTemplate && typeof projectJson.sourceTemplate === "string" && projectJson.sourceTemplate.trim()) return {
|
|
@@ -521,12 +521,12 @@ Run 'scaffold-mcp scaffold list --help' for more info.`;
|
|
|
521
521
|
* @param sourceTemplate - The template identifier
|
|
522
522
|
*/
|
|
523
523
|
static async createProjectJson(projectPath, projectName, sourceTemplate) {
|
|
524
|
-
const projectJsonPath =
|
|
524
|
+
const projectJsonPath = nodePath.join(projectPath, "project.json");
|
|
525
525
|
try {
|
|
526
526
|
let projectJson;
|
|
527
527
|
if (await pathExists(projectJsonPath)) projectJson = await readJson(projectJsonPath);
|
|
528
528
|
else {
|
|
529
|
-
const relativePath =
|
|
529
|
+
const relativePath = nodePath.relative(projectPath, process.cwd());
|
|
530
530
|
projectJson = {
|
|
531
531
|
name: projectName,
|
|
532
532
|
$schema: relativePath ? `${relativePath}/node_modules/nx/schemas/project-schema.json` : "node_modules/nx/schemas/project-schema.json",
|
|
@@ -578,15 +578,15 @@ var ProjectFinderService = class {
|
|
|
578
578
|
* @returns Project configuration or null if not found
|
|
579
579
|
*/
|
|
580
580
|
async findProjectForFile(filePath) {
|
|
581
|
-
const normalizedPath =
|
|
582
|
-
let currentDir =
|
|
581
|
+
const normalizedPath = nodePath.isAbsolute(filePath) ? filePath : nodePath.join(this.workspaceRoot, filePath);
|
|
582
|
+
let currentDir = nodePath.dirname(normalizedPath);
|
|
583
583
|
while (currentDir !== "/" && currentDir.startsWith(this.workspaceRoot)) {
|
|
584
|
-
const projectJsonPath =
|
|
584
|
+
const projectJsonPath = nodePath.join(currentDir, "project.json");
|
|
585
585
|
try {
|
|
586
586
|
const project = await this.loadProjectConfig(projectJsonPath);
|
|
587
587
|
if (project) return project;
|
|
588
588
|
} catch {}
|
|
589
|
-
currentDir =
|
|
589
|
+
currentDir = nodePath.dirname(currentDir);
|
|
590
590
|
}
|
|
591
591
|
return null;
|
|
592
592
|
}
|
|
@@ -597,15 +597,15 @@ var ProjectFinderService = class {
|
|
|
597
597
|
* @returns Project configuration or null if not found
|
|
598
598
|
*/
|
|
599
599
|
findProjectForFileSync(filePath) {
|
|
600
|
-
const normalizedPath =
|
|
601
|
-
let currentDir =
|
|
600
|
+
const normalizedPath = nodePath.isAbsolute(filePath) ? filePath : nodePath.join(this.workspaceRoot, filePath);
|
|
601
|
+
let currentDir = nodePath.dirname(normalizedPath);
|
|
602
602
|
while (currentDir !== "/" && currentDir.startsWith(this.workspaceRoot)) {
|
|
603
|
-
const projectJsonPath =
|
|
603
|
+
const projectJsonPath = nodePath.join(currentDir, "project.json");
|
|
604
604
|
try {
|
|
605
605
|
const project = this.loadProjectConfigSync(projectJsonPath);
|
|
606
606
|
if (project) return project;
|
|
607
607
|
} catch {}
|
|
608
|
-
currentDir =
|
|
608
|
+
currentDir = nodePath.dirname(currentDir);
|
|
609
609
|
}
|
|
610
610
|
return null;
|
|
611
611
|
}
|
|
@@ -618,8 +618,8 @@ var ProjectFinderService = class {
|
|
|
618
618
|
const content = await fs.readFile(projectJsonPath, "utf-8");
|
|
619
619
|
const config = JSON.parse(content);
|
|
620
620
|
const projectConfig = {
|
|
621
|
-
name: config.name ||
|
|
622
|
-
root:
|
|
621
|
+
name: config.name || nodePath.basename(nodePath.dirname(projectJsonPath)),
|
|
622
|
+
root: nodePath.dirname(projectJsonPath),
|
|
623
623
|
sourceTemplate: config.sourceTemplate,
|
|
624
624
|
projectType: config.projectType
|
|
625
625
|
};
|
|
@@ -638,8 +638,8 @@ var ProjectFinderService = class {
|
|
|
638
638
|
const content = readFileSync$1(projectJsonPath, "utf-8");
|
|
639
639
|
const config = JSON.parse(content);
|
|
640
640
|
const projectConfig = {
|
|
641
|
-
name: config.name ||
|
|
642
|
-
root:
|
|
641
|
+
name: config.name || nodePath.basename(nodePath.dirname(projectJsonPath)),
|
|
642
|
+
root: nodePath.dirname(projectJsonPath),
|
|
643
643
|
sourceTemplate: config.sourceTemplate,
|
|
644
644
|
projectType: config.projectType
|
|
645
645
|
};
|
|
@@ -699,7 +699,7 @@ var ScaffoldProcessingService = class {
|
|
|
699
699
|
* Now supports tracking existing files separately from created files
|
|
700
700
|
*/
|
|
701
701
|
async copyAndProcess(sourcePath, targetPath, variables, createdFiles, existingFiles) {
|
|
702
|
-
await this.fileSystem.ensureDir(
|
|
702
|
+
await this.fileSystem.ensureDir(nodePath.dirname(targetPath));
|
|
703
703
|
if (await this.fileSystem.pathExists(targetPath) && existingFiles) {
|
|
704
704
|
await this.trackExistingFiles(targetPath, existingFiles);
|
|
705
705
|
return;
|
|
@@ -721,7 +721,7 @@ var ScaffoldProcessingService = class {
|
|
|
721
721
|
}
|
|
722
722
|
for (const item of items) {
|
|
723
723
|
if (!item) continue;
|
|
724
|
-
const itemPath =
|
|
724
|
+
const itemPath = nodePath.join(dirPath, item);
|
|
725
725
|
try {
|
|
726
726
|
const stat$1 = await this.fileSystem.stat(itemPath);
|
|
727
727
|
if (stat$1.isDirectory()) await this.trackCreatedFilesRecursive(itemPath, createdFiles);
|
|
@@ -744,7 +744,7 @@ var ScaffoldProcessingService = class {
|
|
|
744
744
|
}
|
|
745
745
|
for (const item of items) {
|
|
746
746
|
if (!item) continue;
|
|
747
|
-
const itemPath =
|
|
747
|
+
const itemPath = nodePath.join(dirPath, item);
|
|
748
748
|
try {
|
|
749
749
|
const stat$1 = await this.fileSystem.stat(itemPath);
|
|
750
750
|
if (stat$1.isDirectory()) await this.trackExistingFilesRecursive(itemPath, existingFiles);
|
|
@@ -756,6 +756,27 @@ var ScaffoldProcessingService = class {
|
|
|
756
756
|
}
|
|
757
757
|
};
|
|
758
758
|
|
|
759
|
+
//#endregion
|
|
760
|
+
//#region src/utils/fallbacks.ts
|
|
761
|
+
function resolveFallbackConfig(config) {
|
|
762
|
+
if (!config) return {};
|
|
763
|
+
const tool = ("fallbackTool" in config ? config.fallbackTool : void 0) ?? ("fallback-tool" in config ? config["fallback-tool"] : void 0);
|
|
764
|
+
const fallbackConfig = ("fallbackToolConfig" in config ? config.fallbackToolConfig : void 0) ?? ("fallback-tool-config" in config ? config["fallback-tool-config"] : void 0);
|
|
765
|
+
if (tool) return {
|
|
766
|
+
tool,
|
|
767
|
+
config: fallbackConfig
|
|
768
|
+
};
|
|
769
|
+
const firstValidFallback = config.fallbacks?.find((entry) => isFallbackConfigEntry(entry));
|
|
770
|
+
if (!firstValidFallback) return {};
|
|
771
|
+
return {
|
|
772
|
+
tool: firstValidFallback.tool,
|
|
773
|
+
config: firstValidFallback.config
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
function isFallbackConfigEntry(entry) {
|
|
777
|
+
return Boolean(entry?.tool && typeof entry.tool === "string");
|
|
778
|
+
}
|
|
779
|
+
|
|
759
780
|
//#endregion
|
|
760
781
|
//#region src/utils/generateStableId.ts
|
|
761
782
|
/**
|
|
@@ -871,12 +892,12 @@ async function gitInit(projectPath) {
|
|
|
871
892
|
* }
|
|
872
893
|
*/
|
|
873
894
|
async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
874
|
-
let currentPath =
|
|
875
|
-
const rootPath =
|
|
895
|
+
let currentPath = nodePath.resolve(startPath);
|
|
896
|
+
const rootPath = nodePath.parse(currentPath).root;
|
|
876
897
|
while (true) {
|
|
877
|
-
if (await pathExists(
|
|
898
|
+
if (await pathExists(nodePath.join(currentPath, ".git"))) return currentPath;
|
|
878
899
|
if (currentPath === rootPath) return null;
|
|
879
|
-
currentPath =
|
|
900
|
+
currentPath = nodePath.dirname(currentPath);
|
|
880
901
|
}
|
|
881
902
|
}
|
|
882
903
|
/**
|
|
@@ -958,7 +979,7 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
958
979
|
"core.sparseCheckout",
|
|
959
980
|
"true"
|
|
960
981
|
], tempFolder);
|
|
961
|
-
await writeFile(
|
|
982
|
+
await writeFile(nodePath.join(tempFolder, ".git", "info", "sparse-checkout"), `${subdirectory}\n`);
|
|
962
983
|
await execGit([
|
|
963
984
|
"pull",
|
|
964
985
|
"--depth=1",
|
|
@@ -966,7 +987,7 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
966
987
|
"--",
|
|
967
988
|
branch
|
|
968
989
|
], tempFolder);
|
|
969
|
-
const sourceDir =
|
|
990
|
+
const sourceDir = nodePath.join(tempFolder, subdirectory);
|
|
970
991
|
if (!await pathExists(sourceDir)) throw new Error(`Subdirectory '${subdirectory}' not found in repository at branch '${branch}'`);
|
|
971
992
|
if (await pathExists(targetFolder)) throw new Error(`Target folder already exists: ${targetFolder}`);
|
|
972
993
|
await move(sourceDir, targetFolder);
|
|
@@ -993,7 +1014,7 @@ async function cloneRepository(repoUrl, targetFolder) {
|
|
|
993
1014
|
repoUrl,
|
|
994
1015
|
targetFolder
|
|
995
1016
|
]);
|
|
996
|
-
const gitFolder =
|
|
1017
|
+
const gitFolder = nodePath.join(targetFolder, ".git");
|
|
997
1018
|
if (await pathExists(gitFolder)) await remove(gitFolder);
|
|
998
1019
|
}
|
|
999
1020
|
/**
|
|
@@ -1210,7 +1231,7 @@ const MONOREPO_INDICATOR_FILES = [
|
|
|
1210
1231
|
*/
|
|
1211
1232
|
async function detectProjectType(workspaceRoot) {
|
|
1212
1233
|
const indicators = [];
|
|
1213
|
-
const toolkitYamlPath =
|
|
1234
|
+
const toolkitYamlPath = nodePath.join(workspaceRoot, "toolkit.yaml");
|
|
1214
1235
|
if (await pathExists(toolkitYamlPath)) try {
|
|
1215
1236
|
const content = await fs.readFile(toolkitYamlPath, "utf-8");
|
|
1216
1237
|
const config = yaml.load(content);
|
|
@@ -1222,14 +1243,14 @@ async function detectProjectType(workspaceRoot) {
|
|
|
1222
1243
|
};
|
|
1223
1244
|
}
|
|
1224
1245
|
} catch {}
|
|
1225
|
-
for (const filename of MONOREPO_INDICATOR_FILES) if (await pathExists(
|
|
1246
|
+
for (const filename of MONOREPO_INDICATOR_FILES) if (await pathExists(nodePath.join(workspaceRoot, filename))) {
|
|
1226
1247
|
indicators.push(`${filename} found`);
|
|
1227
1248
|
return {
|
|
1228
1249
|
projectType: ProjectType.MONOREPO,
|
|
1229
1250
|
indicators
|
|
1230
1251
|
};
|
|
1231
1252
|
}
|
|
1232
|
-
const packageJsonPath =
|
|
1253
|
+
const packageJsonPath = nodePath.join(workspaceRoot, "package.json");
|
|
1233
1254
|
if (await pathExists(packageJsonPath)) try {
|
|
1234
1255
|
if ((await readJson(packageJsonPath)).workspaces) {
|
|
1235
1256
|
indicators.push("package.json with workspaces found");
|
|
@@ -1247,4 +1268,4 @@ async function detectProjectType(workspaceRoot) {
|
|
|
1247
1268
|
}
|
|
1248
1269
|
|
|
1249
1270
|
//#endregion
|
|
1250
|
-
export { ConfigSource, ProjectConfigResolver, ProjectFinderService, ProjectType, ScaffoldProcessingService, TemplatesManagerService, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, sections, stat, statSync, writeFile, writeFileSync };
|
|
1271
|
+
export { ConfigSource, ProjectConfigResolver, ProjectFinderService, ProjectType, ScaffoldProcessingService, TemplatesManagerService, accessSync, cloneRepository, cloneSubdirectory, copy, detectProjectType, ensureDir, fetchGitHubDirectoryContents, findWorkspaceRoot, generateStableId, gitInit, icons, log, logger, messages, mkdir, mkdirSync, move, parseGitHubUrl, pathExists, pathExistsSync, print, readFile, readFileSync, readJson, readJsonSync, readdir, remove, resolveFallbackConfig, sections, stat, statSync, writeFile, writeFileSync };
|
package/package.json
CHANGED