@agiflowai/aicode-toolkit 1.0.4 → 1.0.5
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/cli.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_services = require('./services-
|
|
2
|
+
const require_services = require('./services-DIUrmi_K.cjs');
|
|
3
3
|
const require_mcp = require('./mcp-Dwt8nYQV.cjs');
|
|
4
4
|
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
5
|
-
let fs_extra = require("fs-extra");
|
|
6
|
-
fs_extra = require_services.__toESM(fs_extra);
|
|
7
5
|
let node_path = require("node:path");
|
|
8
6
|
node_path = require_services.__toESM(node_path);
|
|
9
7
|
let commander = require("commander");
|
|
@@ -13,7 +11,7 @@ ora = require_services.__toESM(ora);
|
|
|
13
11
|
let xstate = require("xstate");
|
|
14
12
|
|
|
15
13
|
//#region package.json
|
|
16
|
-
var version = "1.0.
|
|
14
|
+
var version = "1.0.5";
|
|
17
15
|
|
|
18
16
|
//#endregion
|
|
19
17
|
//#region src/commands/add.ts
|
|
@@ -31,12 +29,12 @@ const addCommand = new commander.Command("add").description("Add a template to t
|
|
|
31
29
|
process.exit(1);
|
|
32
30
|
}
|
|
33
31
|
const targetFolder = node_path.default.join(templatesPath, `${templateType}s`, templateName);
|
|
34
|
-
if (await
|
|
32
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(targetFolder)) {
|
|
35
33
|
__agiflowai_aicode_utils.messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
|
|
36
34
|
process.exit(1);
|
|
37
35
|
}
|
|
38
36
|
__agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
|
|
39
|
-
await
|
|
37
|
+
await (0, __agiflowai_aicode_utils.ensureDir)(node_path.default.dirname(targetFolder));
|
|
40
38
|
const parsedUrl = require_services.parseGitHubUrl(templateUrl);
|
|
41
39
|
try {
|
|
42
40
|
if (parsedUrl.isSubdirectory && parsedUrl.branch && parsedUrl.subdirectory) {
|
|
@@ -48,7 +46,7 @@ const addCommand = new commander.Command("add").description("Add a template to t
|
|
|
48
46
|
__agiflowai_aicode_utils.print.indent(targetFolder);
|
|
49
47
|
const configFiles = [node_path.default.join(targetFolder, "boilerplate.yaml"), node_path.default.join(targetFolder, "scaffold.yaml")];
|
|
50
48
|
let hasConfig = false;
|
|
51
|
-
for (const configFile of configFiles) if (await
|
|
49
|
+
for (const configFile of configFiles) if (await (0, __agiflowai_aicode_utils.pathExists)(configFile)) {
|
|
52
50
|
__agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.config} Configuration file found:`);
|
|
53
51
|
__agiflowai_aicode_utils.print.indent(node_path.default.basename(configFile));
|
|
54
52
|
hasConfig = true;
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { r as MCP_SERVER_INFO, t as MCPServer } from "./mcp-C3HR_ZNF.mjs";
|
|
3
|
-
import { a as SpecToolService, c as cloneSubdirectory, f as parseGitHubUrl, h as CodingAgentService, i as SpecTool, n as TemplateSelectionService, o as NewProjectService, p as displayBanner, r as SPEC_TOOL_INFO, s as cloneRepository, u as findWorkspaceRoot } from "./services-
|
|
4
|
-
import { ProjectType, TemplatesManagerService, detectProjectType, icons, messages, print, sections } from "@agiflowai/aicode-utils";
|
|
5
|
-
import * as fs from "fs-extra";
|
|
3
|
+
import { a as SpecToolService, c as cloneSubdirectory, f as parseGitHubUrl, h as CodingAgentService, i as SpecTool, n as TemplateSelectionService, o as NewProjectService, p as displayBanner, r as SPEC_TOOL_INFO, s as cloneRepository, u as findWorkspaceRoot } from "./services-BvnOGCDG.mjs";
|
|
4
|
+
import { ProjectType, TemplatesManagerService, detectProjectType, ensureDir, icons, messages, pathExists, print, sections } from "@agiflowai/aicode-utils";
|
|
6
5
|
import path from "node:path";
|
|
7
6
|
import { Command } from "commander";
|
|
8
7
|
import { confirm, input, select } from "@inquirer/prompts";
|
|
@@ -10,7 +9,7 @@ import ora from "ora";
|
|
|
10
9
|
import { assign, createActor, createMachine, fromPromise } from "xstate";
|
|
11
10
|
|
|
12
11
|
//#region package.json
|
|
13
|
-
var version = "1.0.
|
|
12
|
+
var version = "1.0.5";
|
|
14
13
|
|
|
15
14
|
//#endregion
|
|
16
15
|
//#region src/commands/add.ts
|
|
@@ -28,12 +27,12 @@ const addCommand = new Command("add").description("Add a template to templates f
|
|
|
28
27
|
process.exit(1);
|
|
29
28
|
}
|
|
30
29
|
const targetFolder = path.join(templatesPath, `${templateType}s`, templateName);
|
|
31
|
-
if (await
|
|
30
|
+
if (await pathExists(targetFolder)) {
|
|
32
31
|
messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
|
|
33
32
|
process.exit(1);
|
|
34
33
|
}
|
|
35
34
|
print.info(`${icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
|
|
36
|
-
await
|
|
35
|
+
await ensureDir(path.dirname(targetFolder));
|
|
37
36
|
const parsedUrl = parseGitHubUrl(templateUrl);
|
|
38
37
|
try {
|
|
39
38
|
if (parsedUrl.isSubdirectory && parsedUrl.branch && parsedUrl.subdirectory) {
|
|
@@ -45,7 +44,7 @@ const addCommand = new Command("add").description("Add a template to templates f
|
|
|
45
44
|
print.indent(targetFolder);
|
|
46
45
|
const configFiles = [path.join(targetFolder, "boilerplate.yaml"), path.join(targetFolder, "scaffold.yaml")];
|
|
47
46
|
let hasConfig = false;
|
|
48
|
-
for (const configFile of configFiles) if (await
|
|
47
|
+
for (const configFile of configFiles) if (await pathExists(configFile)) {
|
|
49
48
|
print.header(`\n${icons.config} Configuration file found:`);
|
|
50
49
|
print.indent(path.basename(configFile));
|
|
51
50
|
hasConfig = true;
|
|
@@ -593,11 +592,11 @@ const initActors = {
|
|
|
593
592
|
}),
|
|
594
593
|
checkTemplatesFolder: fromPromise(async ({ input: actorInput }) => {
|
|
595
594
|
try {
|
|
596
|
-
const fs
|
|
595
|
+
const fs = await import("node:fs/promises");
|
|
597
596
|
const defaultTemplatesPath = path.join(actorInput.workspaceRoot, "templates");
|
|
598
597
|
let templatesExists = false;
|
|
599
598
|
try {
|
|
600
|
-
await fs
|
|
599
|
+
await fs.access(defaultTemplatesPath);
|
|
601
600
|
templatesExists = true;
|
|
602
601
|
} catch {
|
|
603
602
|
templatesExists = false;
|
|
@@ -625,7 +624,7 @@ const initActors = {
|
|
|
625
624
|
print.info("");
|
|
626
625
|
finalTemplatesPath = path.join(actorInput.workspaceRoot, customDir.trim());
|
|
627
626
|
try {
|
|
628
|
-
await fs
|
|
627
|
+
await fs.mkdir(finalTemplatesPath, { recursive: true });
|
|
629
628
|
print.success(`Created templates directory at: ${finalTemplatesPath}`);
|
|
630
629
|
} catch (error) {
|
|
631
630
|
throw new Error(`Failed to create templates directory at ${finalTemplatesPath}: ${error.message}`);
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import "./mcp-C3HR_ZNF.mjs";
|
|
2
|
-
import { _ as THEME, c as cloneSubdirectory, d as gitInit, f as parseGitHubUrl, g as BANNER_GRADIENT, h as CodingAgentService, l as fetchGitHubDirectoryContents, m as displayCompactBanner, n as TemplateSelectionService, o as NewProjectService, p as displayBanner, s as cloneRepository, t as TemplatesService, u as findWorkspaceRoot } from "./services-
|
|
2
|
+
import { _ as THEME, c as cloneSubdirectory, d as gitInit, f as parseGitHubUrl, g as BANNER_GRADIENT, h as CodingAgentService, l as fetchGitHubDirectoryContents, m as displayCompactBanner, n as TemplateSelectionService, o as NewProjectService, p as displayBanner, s as cloneRepository, t as TemplatesService, u as findWorkspaceRoot } from "./services-BvnOGCDG.mjs";
|
|
3
3
|
|
|
4
4
|
export { BANNER_GRADIENT, CodingAgentService, NewProjectService, THEME, TemplateSelectionService, TemplatesService, cloneRepository, cloneSubdirectory, displayBanner, displayCompactBanner, fetchGitHubDirectoryContents, findWorkspaceRoot, gitInit, parseGitHubUrl };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CLAUDE_CODE, CODEX, CURSOR, ClaudeCodeService, CodexService, CursorService, GEMINI_CLI, GITHUB_COPILOT, GeminiCliService, GitHubCopilotService, NONE } from "@agiflowai/coding-agent-bridge";
|
|
2
|
-
import { ProjectType, messages, print } from "@agiflowai/aicode-utils";
|
|
3
|
-
import * as fs$1 from "fs-extra";
|
|
2
|
+
import { ProjectType, copy, ensureDir, messages, mkdir, move, pathExists, print, readFile, readdir, remove, writeFile } from "@agiflowai/aicode-utils";
|
|
4
3
|
import chalk from "chalk";
|
|
5
4
|
import gradient from "gradient-string";
|
|
6
5
|
import path from "node:path";
|
|
@@ -326,8 +325,7 @@ async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
|
326
325
|
let currentPath = path.resolve(startPath);
|
|
327
326
|
const rootPath = path.parse(currentPath).root;
|
|
328
327
|
while (true) {
|
|
329
|
-
|
|
330
|
-
if (await fs$1.pathExists(gitPath)) return currentPath;
|
|
328
|
+
if (await pathExists(path.join(currentPath, ".git"))) return currentPath;
|
|
331
329
|
if (currentPath === rootPath) return null;
|
|
332
330
|
currentPath = path.dirname(currentPath);
|
|
333
331
|
}
|
|
@@ -383,8 +381,7 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
383
381
|
"core.sparseCheckout",
|
|
384
382
|
"true"
|
|
385
383
|
], tempFolder);
|
|
386
|
-
|
|
387
|
-
await fs$1.writeFile(sparseCheckoutFile, `${subdirectory}\n`);
|
|
384
|
+
await writeFile(path.join(tempFolder, ".git", "info", "sparse-checkout"), `${subdirectory}\n`);
|
|
388
385
|
await execGit([
|
|
389
386
|
"pull",
|
|
390
387
|
"--depth=1",
|
|
@@ -392,12 +389,12 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
392
389
|
branch
|
|
393
390
|
], tempFolder);
|
|
394
391
|
const sourceDir = path.join(tempFolder, subdirectory);
|
|
395
|
-
if (!await
|
|
396
|
-
if (await
|
|
397
|
-
await
|
|
398
|
-
await
|
|
392
|
+
if (!await pathExists(sourceDir)) throw new Error(`Subdirectory '${subdirectory}' not found in repository at branch '${branch}'`);
|
|
393
|
+
if (await pathExists(targetFolder)) throw new Error(`Target folder already exists: ${targetFolder}`);
|
|
394
|
+
await move(sourceDir, targetFolder);
|
|
395
|
+
await remove(tempFolder);
|
|
399
396
|
} catch (error) {
|
|
400
|
-
if (await
|
|
397
|
+
if (await pathExists(tempFolder)) await remove(tempFolder);
|
|
401
398
|
throw error;
|
|
402
399
|
}
|
|
403
400
|
}
|
|
@@ -411,7 +408,7 @@ async function cloneRepository(repoUrl, targetFolder) {
|
|
|
411
408
|
targetFolder
|
|
412
409
|
]);
|
|
413
410
|
const gitFolder = path.join(targetFolder, ".git");
|
|
414
|
-
if (await
|
|
411
|
+
if (await pathExists(gitFolder)) await remove(gitFolder);
|
|
415
412
|
}
|
|
416
413
|
/**
|
|
417
414
|
* Fetch directory listing from GitHub API
|
|
@@ -526,7 +523,7 @@ var NewProjectService = class {
|
|
|
526
523
|
*/
|
|
527
524
|
async createProjectDirectory(projectPath, projectName) {
|
|
528
525
|
try {
|
|
529
|
-
await
|
|
526
|
+
await mkdir(projectPath, { recursive: false });
|
|
530
527
|
} catch (error) {
|
|
531
528
|
if (error.code === "EEXIST") throw new Error(`Directory '${projectName}' already exists. Please choose a different name.`);
|
|
532
529
|
throw error;
|
|
@@ -543,7 +540,7 @@ var NewProjectService = class {
|
|
|
543
540
|
if (parsed.isSubdirectory && parsed.branch && parsed.subdirectory) await cloneSubdirectory(parsed.repoUrl, parsed.branch, parsed.subdirectory, projectPath);
|
|
544
541
|
else await cloneRepository(parsed.repoUrl, projectPath);
|
|
545
542
|
} catch (error) {
|
|
546
|
-
await
|
|
543
|
+
await remove(projectPath);
|
|
547
544
|
throw new Error(`Failed to clone repository: ${error.message}`);
|
|
548
545
|
}
|
|
549
546
|
}
|
|
@@ -771,7 +768,7 @@ var TemplateSelectionService = class {
|
|
|
771
768
|
*/
|
|
772
769
|
async downloadTemplatesToTmp(repoConfig) {
|
|
773
770
|
try {
|
|
774
|
-
await
|
|
771
|
+
await ensureDir(this.tmpDir);
|
|
775
772
|
const contents = await fetchGitHubDirectoryContents(repoConfig.owner, repoConfig.repo, repoConfig.path, repoConfig.branch);
|
|
776
773
|
const templateDirs = contents.filter((item) => item.type === "dir");
|
|
777
774
|
const globalFiles = contents.filter((item) => item.type === "file" && item.name === "RULES.yaml");
|
|
@@ -789,8 +786,7 @@ var TemplateSelectionService = class {
|
|
|
789
786
|
const targetFile = path.join(this.tmpDir, "RULES.yaml");
|
|
790
787
|
const response = await fetch(rulesUrl);
|
|
791
788
|
if (response.ok) {
|
|
792
|
-
|
|
793
|
-
await fs$1.writeFile(targetFile, content, "utf-8");
|
|
789
|
+
await writeFile(targetFile, await response.text(), "utf-8");
|
|
794
790
|
print.success("Downloaded global RULES.yaml");
|
|
795
791
|
}
|
|
796
792
|
}
|
|
@@ -807,7 +803,7 @@ var TemplateSelectionService = class {
|
|
|
807
803
|
*/
|
|
808
804
|
async listTemplates() {
|
|
809
805
|
try {
|
|
810
|
-
const entries = await
|
|
806
|
+
const entries = await readdir(this.tmpDir, { withFileTypes: true });
|
|
811
807
|
const templates = [];
|
|
812
808
|
for (const entry of entries) if (entry.isDirectory()) {
|
|
813
809
|
const templatePath = path.join(this.tmpDir, entry.name);
|
|
@@ -833,27 +829,27 @@ var TemplateSelectionService = class {
|
|
|
833
829
|
async copyTemplates(templateNames, destinationPath, projectType, selectedMcpServers) {
|
|
834
830
|
try {
|
|
835
831
|
if (projectType === ProjectType.MONOLITH && templateNames.length > 1) throw new Error("Monolith projects can only use a single template");
|
|
836
|
-
await
|
|
832
|
+
await ensureDir(destinationPath);
|
|
837
833
|
print.info(`\nCopying templates to ${destinationPath}...`);
|
|
838
834
|
for (const templateName of templateNames) {
|
|
839
835
|
const sourcePath = path.join(this.tmpDir, templateName);
|
|
840
836
|
const targetPath = path.join(destinationPath, templateName);
|
|
841
|
-
if (!await
|
|
842
|
-
if (await
|
|
837
|
+
if (!await pathExists(sourcePath)) throw new Error(`Template '${templateName}' not found in downloaded templates`);
|
|
838
|
+
if (await pathExists(targetPath)) {
|
|
843
839
|
print.info(`Skipping ${templateName} (already exists)`);
|
|
844
840
|
continue;
|
|
845
841
|
}
|
|
846
842
|
print.info(`Copying ${templateName}...`);
|
|
847
843
|
if (selectedMcpServers && selectedMcpServers.length > 0) await this.copyTemplateWithMcpFilter(sourcePath, targetPath, selectedMcpServers);
|
|
848
|
-
else await
|
|
844
|
+
else await copy(sourcePath, targetPath);
|
|
849
845
|
print.success(`Copied ${templateName}`);
|
|
850
846
|
}
|
|
851
847
|
const globalRulesSource = path.join(this.tmpDir, "RULES.yaml");
|
|
852
848
|
const globalRulesTarget = path.join(destinationPath, "RULES.yaml");
|
|
853
|
-
if (await
|
|
854
|
-
if (!await
|
|
849
|
+
if (await pathExists(globalRulesSource)) {
|
|
850
|
+
if (!await pathExists(globalRulesTarget)) {
|
|
855
851
|
print.info("Copying global RULES.yaml...");
|
|
856
|
-
await
|
|
852
|
+
await copy(globalRulesSource, globalRulesTarget);
|
|
857
853
|
print.success("Copied global RULES.yaml");
|
|
858
854
|
}
|
|
859
855
|
}
|
|
@@ -873,19 +869,19 @@ var TemplateSelectionService = class {
|
|
|
873
869
|
const architectFiles = MCP_CONFIG_FILES$1[MCPServer$1.ARCHITECT];
|
|
874
870
|
const hasArchitect = selectedMcpServers.includes(MCPServer$1.ARCHITECT);
|
|
875
871
|
const hasScaffold = selectedMcpServers.includes(MCPServer$1.SCAFFOLD);
|
|
876
|
-
await
|
|
877
|
-
const entries = await
|
|
872
|
+
await ensureDir(targetPath);
|
|
873
|
+
const entries = await readdir(sourcePath, { withFileTypes: true });
|
|
878
874
|
for (const entry of entries) {
|
|
879
875
|
const entrySourcePath = path.join(sourcePath, entry.name);
|
|
880
876
|
const entryTargetPath = path.join(targetPath, entry.name);
|
|
881
877
|
const isArchitectFile = architectFiles.includes(entry.name);
|
|
882
|
-
if (hasArchitect && hasScaffold) if (entry.isDirectory()) await
|
|
883
|
-
else await
|
|
878
|
+
if (hasArchitect && hasScaffold) if (entry.isDirectory()) await copy(entrySourcePath, entryTargetPath);
|
|
879
|
+
else await copy(entrySourcePath, entryTargetPath);
|
|
884
880
|
else if (hasArchitect && !hasScaffold) {
|
|
885
|
-
if (isArchitectFile) await
|
|
881
|
+
if (isArchitectFile) await copy(entrySourcePath, entryTargetPath);
|
|
886
882
|
} else if (!hasArchitect && hasScaffold) {
|
|
887
|
-
if (!isArchitectFile) if (entry.isDirectory()) await
|
|
888
|
-
else await
|
|
883
|
+
if (!isArchitectFile) if (entry.isDirectory()) await copy(entrySourcePath, entryTargetPath);
|
|
884
|
+
else await copy(entrySourcePath, entryTargetPath);
|
|
889
885
|
}
|
|
890
886
|
}
|
|
891
887
|
}
|
|
@@ -897,15 +893,15 @@ var TemplateSelectionService = class {
|
|
|
897
893
|
async readTemplateDescription(templatePath) {
|
|
898
894
|
try {
|
|
899
895
|
const scaffoldYamlPath = path.join(templatePath, "scaffold.yaml");
|
|
900
|
-
if (await
|
|
896
|
+
if (await pathExists(scaffoldYamlPath)) {
|
|
901
897
|
const yaml = await import("js-yaml");
|
|
902
|
-
const content = await
|
|
898
|
+
const content = await readFile(scaffoldYamlPath, "utf-8");
|
|
903
899
|
const scaffoldConfig = yaml.load(content);
|
|
904
900
|
if (scaffoldConfig?.description) return scaffoldConfig.description;
|
|
905
901
|
if (scaffoldConfig?.boilerplate?.[0]?.description) return scaffoldConfig.boilerplate[0].description;
|
|
906
902
|
}
|
|
907
903
|
const readmePath = path.join(templatePath, "README.md");
|
|
908
|
-
if (await
|
|
904
|
+
if (await pathExists(readmePath)) return (await readFile(readmePath, "utf-8")).split("\n\n")[0].substring(0, 200).trim();
|
|
909
905
|
return;
|
|
910
906
|
} catch {
|
|
911
907
|
return;
|
|
@@ -922,7 +918,7 @@ var TemplateSelectionService = class {
|
|
|
922
918
|
*/
|
|
923
919
|
async cleanup() {
|
|
924
920
|
try {
|
|
925
|
-
if (await
|
|
921
|
+
if (await pathExists(this.tmpDir)) await remove(this.tmpDir);
|
|
926
922
|
} catch (error) {
|
|
927
923
|
print.warning(`Warning: Failed to clean up tmp directory: ${error.message}`);
|
|
928
924
|
}
|
|
@@ -967,7 +963,7 @@ var TemplatesService = class {
|
|
|
967
963
|
let _skipped = 0;
|
|
968
964
|
for (const template of templateDirs) {
|
|
969
965
|
const targetFolder = path.join(templatesPath, template.name);
|
|
970
|
-
if (await
|
|
966
|
+
if (await pathExists(targetFolder)) {
|
|
971
967
|
print.info(`Skipping ${template.name} (already exists)`);
|
|
972
968
|
_skipped++;
|
|
973
969
|
continue;
|
|
@@ -987,8 +983,8 @@ var TemplatesService = class {
|
|
|
987
983
|
* @param templatesPath - Path where templates folder should be created
|
|
988
984
|
*/
|
|
989
985
|
async initializeTemplatesFolder(templatesPath) {
|
|
990
|
-
await
|
|
991
|
-
await
|
|
986
|
+
await ensureDir(templatesPath);
|
|
987
|
+
await writeFile(path.join(templatesPath, "README.md"), `# Templates
|
|
992
988
|
|
|
993
989
|
This folder contains boilerplate templates and scaffolding methods for your projects.
|
|
994
990
|
|
|
@@ -23,8 +23,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
let __agiflowai_coding_agent_bridge = require("@agiflowai/coding-agent-bridge");
|
|
25
25
|
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
26
|
-
let fs_extra = require("fs-extra");
|
|
27
|
-
fs_extra = __toESM(fs_extra);
|
|
28
26
|
let chalk = require("chalk");
|
|
29
27
|
chalk = __toESM(chalk);
|
|
30
28
|
let gradient_string = require("gradient-string");
|
|
@@ -355,8 +353,7 @@ async function findWorkspaceRoot(startPath = process.cwd()) {
|
|
|
355
353
|
let currentPath = node_path.default.resolve(startPath);
|
|
356
354
|
const rootPath = node_path.default.parse(currentPath).root;
|
|
357
355
|
while (true) {
|
|
358
|
-
|
|
359
|
-
if (await fs_extra.pathExists(gitPath)) return currentPath;
|
|
356
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(node_path.default.join(currentPath, ".git"))) return currentPath;
|
|
360
357
|
if (currentPath === rootPath) return null;
|
|
361
358
|
currentPath = node_path.default.dirname(currentPath);
|
|
362
359
|
}
|
|
@@ -412,8 +409,7 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
412
409
|
"core.sparseCheckout",
|
|
413
410
|
"true"
|
|
414
411
|
], tempFolder);
|
|
415
|
-
|
|
416
|
-
await fs_extra.writeFile(sparseCheckoutFile, `${subdirectory}\n`);
|
|
412
|
+
await (0, __agiflowai_aicode_utils.writeFile)(node_path.default.join(tempFolder, ".git", "info", "sparse-checkout"), `${subdirectory}\n`);
|
|
417
413
|
await execGit([
|
|
418
414
|
"pull",
|
|
419
415
|
"--depth=1",
|
|
@@ -421,12 +417,12 @@ async function cloneSubdirectory(repoUrl, branch, subdirectory, targetFolder) {
|
|
|
421
417
|
branch
|
|
422
418
|
], tempFolder);
|
|
423
419
|
const sourceDir = node_path.default.join(tempFolder, subdirectory);
|
|
424
|
-
if (!await
|
|
425
|
-
if (await
|
|
426
|
-
await
|
|
427
|
-
await
|
|
420
|
+
if (!await (0, __agiflowai_aicode_utils.pathExists)(sourceDir)) throw new Error(`Subdirectory '${subdirectory}' not found in repository at branch '${branch}'`);
|
|
421
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(targetFolder)) throw new Error(`Target folder already exists: ${targetFolder}`);
|
|
422
|
+
await (0, __agiflowai_aicode_utils.move)(sourceDir, targetFolder);
|
|
423
|
+
await (0, __agiflowai_aicode_utils.remove)(tempFolder);
|
|
428
424
|
} catch (error) {
|
|
429
|
-
if (await
|
|
425
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(tempFolder)) await (0, __agiflowai_aicode_utils.remove)(tempFolder);
|
|
430
426
|
throw error;
|
|
431
427
|
}
|
|
432
428
|
}
|
|
@@ -440,7 +436,7 @@ async function cloneRepository(repoUrl, targetFolder) {
|
|
|
440
436
|
targetFolder
|
|
441
437
|
]);
|
|
442
438
|
const gitFolder = node_path.default.join(targetFolder, ".git");
|
|
443
|
-
if (await
|
|
439
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(gitFolder)) await (0, __agiflowai_aicode_utils.remove)(gitFolder);
|
|
444
440
|
}
|
|
445
441
|
/**
|
|
446
442
|
* Fetch directory listing from GitHub API
|
|
@@ -555,7 +551,7 @@ var NewProjectService = class {
|
|
|
555
551
|
*/
|
|
556
552
|
async createProjectDirectory(projectPath, projectName) {
|
|
557
553
|
try {
|
|
558
|
-
await
|
|
554
|
+
await (0, __agiflowai_aicode_utils.mkdir)(projectPath, { recursive: false });
|
|
559
555
|
} catch (error) {
|
|
560
556
|
if (error.code === "EEXIST") throw new Error(`Directory '${projectName}' already exists. Please choose a different name.`);
|
|
561
557
|
throw error;
|
|
@@ -572,7 +568,7 @@ var NewProjectService = class {
|
|
|
572
568
|
if (parsed.isSubdirectory && parsed.branch && parsed.subdirectory) await cloneSubdirectory(parsed.repoUrl, parsed.branch, parsed.subdirectory, projectPath);
|
|
573
569
|
else await cloneRepository(parsed.repoUrl, projectPath);
|
|
574
570
|
} catch (error) {
|
|
575
|
-
await
|
|
571
|
+
await (0, __agiflowai_aicode_utils.remove)(projectPath);
|
|
576
572
|
throw new Error(`Failed to clone repository: ${error.message}`);
|
|
577
573
|
}
|
|
578
574
|
}
|
|
@@ -800,7 +796,7 @@ var TemplateSelectionService = class {
|
|
|
800
796
|
*/
|
|
801
797
|
async downloadTemplatesToTmp(repoConfig) {
|
|
802
798
|
try {
|
|
803
|
-
await
|
|
799
|
+
await (0, __agiflowai_aicode_utils.ensureDir)(this.tmpDir);
|
|
804
800
|
const contents = await fetchGitHubDirectoryContents(repoConfig.owner, repoConfig.repo, repoConfig.path, repoConfig.branch);
|
|
805
801
|
const templateDirs = contents.filter((item) => item.type === "dir");
|
|
806
802
|
const globalFiles = contents.filter((item) => item.type === "file" && item.name === "RULES.yaml");
|
|
@@ -818,8 +814,7 @@ var TemplateSelectionService = class {
|
|
|
818
814
|
const targetFile = node_path.default.join(this.tmpDir, "RULES.yaml");
|
|
819
815
|
const response = await fetch(rulesUrl);
|
|
820
816
|
if (response.ok) {
|
|
821
|
-
|
|
822
|
-
await fs_extra.writeFile(targetFile, content, "utf-8");
|
|
817
|
+
await (0, __agiflowai_aicode_utils.writeFile)(targetFile, await response.text(), "utf-8");
|
|
823
818
|
__agiflowai_aicode_utils.print.success("Downloaded global RULES.yaml");
|
|
824
819
|
}
|
|
825
820
|
}
|
|
@@ -836,7 +831,7 @@ var TemplateSelectionService = class {
|
|
|
836
831
|
*/
|
|
837
832
|
async listTemplates() {
|
|
838
833
|
try {
|
|
839
|
-
const entries = await
|
|
834
|
+
const entries = await (0, __agiflowai_aicode_utils.readdir)(this.tmpDir, { withFileTypes: true });
|
|
840
835
|
const templates = [];
|
|
841
836
|
for (const entry of entries) if (entry.isDirectory()) {
|
|
842
837
|
const templatePath = node_path.default.join(this.tmpDir, entry.name);
|
|
@@ -862,27 +857,27 @@ var TemplateSelectionService = class {
|
|
|
862
857
|
async copyTemplates(templateNames, destinationPath, projectType, selectedMcpServers) {
|
|
863
858
|
try {
|
|
864
859
|
if (projectType === __agiflowai_aicode_utils.ProjectType.MONOLITH && templateNames.length > 1) throw new Error("Monolith projects can only use a single template");
|
|
865
|
-
await
|
|
860
|
+
await (0, __agiflowai_aicode_utils.ensureDir)(destinationPath);
|
|
866
861
|
__agiflowai_aicode_utils.print.info(`\nCopying templates to ${destinationPath}...`);
|
|
867
862
|
for (const templateName of templateNames) {
|
|
868
863
|
const sourcePath = node_path.default.join(this.tmpDir, templateName);
|
|
869
864
|
const targetPath = node_path.default.join(destinationPath, templateName);
|
|
870
|
-
if (!await
|
|
871
|
-
if (await
|
|
865
|
+
if (!await (0, __agiflowai_aicode_utils.pathExists)(sourcePath)) throw new Error(`Template '${templateName}' not found in downloaded templates`);
|
|
866
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(targetPath)) {
|
|
872
867
|
__agiflowai_aicode_utils.print.info(`Skipping ${templateName} (already exists)`);
|
|
873
868
|
continue;
|
|
874
869
|
}
|
|
875
870
|
__agiflowai_aicode_utils.print.info(`Copying ${templateName}...`);
|
|
876
871
|
if (selectedMcpServers && selectedMcpServers.length > 0) await this.copyTemplateWithMcpFilter(sourcePath, targetPath, selectedMcpServers);
|
|
877
|
-
else await
|
|
872
|
+
else await (0, __agiflowai_aicode_utils.copy)(sourcePath, targetPath);
|
|
878
873
|
__agiflowai_aicode_utils.print.success(`Copied ${templateName}`);
|
|
879
874
|
}
|
|
880
875
|
const globalRulesSource = node_path.default.join(this.tmpDir, "RULES.yaml");
|
|
881
876
|
const globalRulesTarget = node_path.default.join(destinationPath, "RULES.yaml");
|
|
882
|
-
if (await
|
|
883
|
-
if (!await
|
|
877
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(globalRulesSource)) {
|
|
878
|
+
if (!await (0, __agiflowai_aicode_utils.pathExists)(globalRulesTarget)) {
|
|
884
879
|
__agiflowai_aicode_utils.print.info("Copying global RULES.yaml...");
|
|
885
|
-
await
|
|
880
|
+
await (0, __agiflowai_aicode_utils.copy)(globalRulesSource, globalRulesTarget);
|
|
886
881
|
__agiflowai_aicode_utils.print.success("Copied global RULES.yaml");
|
|
887
882
|
}
|
|
888
883
|
}
|
|
@@ -902,19 +897,19 @@ var TemplateSelectionService = class {
|
|
|
902
897
|
const architectFiles = MCP_CONFIG_FILES$1[MCPServer$1.ARCHITECT];
|
|
903
898
|
const hasArchitect = selectedMcpServers.includes(MCPServer$1.ARCHITECT);
|
|
904
899
|
const hasScaffold = selectedMcpServers.includes(MCPServer$1.SCAFFOLD);
|
|
905
|
-
await
|
|
906
|
-
const entries = await
|
|
900
|
+
await (0, __agiflowai_aicode_utils.ensureDir)(targetPath);
|
|
901
|
+
const entries = await (0, __agiflowai_aicode_utils.readdir)(sourcePath, { withFileTypes: true });
|
|
907
902
|
for (const entry of entries) {
|
|
908
903
|
const entrySourcePath = node_path.default.join(sourcePath, entry.name);
|
|
909
904
|
const entryTargetPath = node_path.default.join(targetPath, entry.name);
|
|
910
905
|
const isArchitectFile = architectFiles.includes(entry.name);
|
|
911
|
-
if (hasArchitect && hasScaffold) if (entry.isDirectory()) await
|
|
912
|
-
else await
|
|
906
|
+
if (hasArchitect && hasScaffold) if (entry.isDirectory()) await (0, __agiflowai_aicode_utils.copy)(entrySourcePath, entryTargetPath);
|
|
907
|
+
else await (0, __agiflowai_aicode_utils.copy)(entrySourcePath, entryTargetPath);
|
|
913
908
|
else if (hasArchitect && !hasScaffold) {
|
|
914
|
-
if (isArchitectFile) await
|
|
909
|
+
if (isArchitectFile) await (0, __agiflowai_aicode_utils.copy)(entrySourcePath, entryTargetPath);
|
|
915
910
|
} else if (!hasArchitect && hasScaffold) {
|
|
916
|
-
if (!isArchitectFile) if (entry.isDirectory()) await
|
|
917
|
-
else await
|
|
911
|
+
if (!isArchitectFile) if (entry.isDirectory()) await (0, __agiflowai_aicode_utils.copy)(entrySourcePath, entryTargetPath);
|
|
912
|
+
else await (0, __agiflowai_aicode_utils.copy)(entrySourcePath, entryTargetPath);
|
|
918
913
|
}
|
|
919
914
|
}
|
|
920
915
|
}
|
|
@@ -926,15 +921,15 @@ var TemplateSelectionService = class {
|
|
|
926
921
|
async readTemplateDescription(templatePath) {
|
|
927
922
|
try {
|
|
928
923
|
const scaffoldYamlPath = node_path.default.join(templatePath, "scaffold.yaml");
|
|
929
|
-
if (await
|
|
924
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(scaffoldYamlPath)) {
|
|
930
925
|
const yaml = await import("js-yaml");
|
|
931
|
-
const content = await
|
|
926
|
+
const content = await (0, __agiflowai_aicode_utils.readFile)(scaffoldYamlPath, "utf-8");
|
|
932
927
|
const scaffoldConfig = yaml.load(content);
|
|
933
928
|
if (scaffoldConfig?.description) return scaffoldConfig.description;
|
|
934
929
|
if (scaffoldConfig?.boilerplate?.[0]?.description) return scaffoldConfig.boilerplate[0].description;
|
|
935
930
|
}
|
|
936
931
|
const readmePath = node_path.default.join(templatePath, "README.md");
|
|
937
|
-
if (await
|
|
932
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(readmePath)) return (await (0, __agiflowai_aicode_utils.readFile)(readmePath, "utf-8")).split("\n\n")[0].substring(0, 200).trim();
|
|
938
933
|
return;
|
|
939
934
|
} catch {
|
|
940
935
|
return;
|
|
@@ -951,7 +946,7 @@ var TemplateSelectionService = class {
|
|
|
951
946
|
*/
|
|
952
947
|
async cleanup() {
|
|
953
948
|
try {
|
|
954
|
-
if (await
|
|
949
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(this.tmpDir)) await (0, __agiflowai_aicode_utils.remove)(this.tmpDir);
|
|
955
950
|
} catch (error) {
|
|
956
951
|
__agiflowai_aicode_utils.print.warning(`Warning: Failed to clean up tmp directory: ${error.message}`);
|
|
957
952
|
}
|
|
@@ -996,7 +991,7 @@ var TemplatesService = class {
|
|
|
996
991
|
let _skipped = 0;
|
|
997
992
|
for (const template of templateDirs) {
|
|
998
993
|
const targetFolder = node_path.default.join(templatesPath, template.name);
|
|
999
|
-
if (await
|
|
994
|
+
if (await (0, __agiflowai_aicode_utils.pathExists)(targetFolder)) {
|
|
1000
995
|
__agiflowai_aicode_utils.print.info(`Skipping ${template.name} (already exists)`);
|
|
1001
996
|
_skipped++;
|
|
1002
997
|
continue;
|
|
@@ -1016,8 +1011,8 @@ var TemplatesService = class {
|
|
|
1016
1011
|
* @param templatesPath - Path where templates folder should be created
|
|
1017
1012
|
*/
|
|
1018
1013
|
async initializeTemplatesFolder(templatesPath) {
|
|
1019
|
-
await
|
|
1020
|
-
await
|
|
1014
|
+
await (0, __agiflowai_aicode_utils.ensureDir)(templatesPath);
|
|
1015
|
+
await (0, __agiflowai_aicode_utils.writeFile)(node_path.default.join(templatesPath, "README.md"), `# Templates
|
|
1021
1016
|
|
|
1022
1017
|
This folder contains boilerplate templates and scaffolding methods for your projects.
|
|
1023
1018
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agiflowai/aicode-toolkit",
|
|
3
3
|
"description": "AI-powered code toolkit CLI for scaffolding, architecture management, and development workflows",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"author": "AgiflowIO",
|
|
7
7
|
"repository": {
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
"commander": "14.0.1",
|
|
43
43
|
"execa": "^9.5.2",
|
|
44
44
|
"express": "^4.21.2",
|
|
45
|
-
"fs-extra": "11.3.2",
|
|
46
45
|
"gradient-string": "^3.0.0",
|
|
47
46
|
"js-yaml": "4.1.0",
|
|
48
47
|
"liquidjs": "10.21.1",
|
|
@@ -51,12 +50,11 @@
|
|
|
51
50
|
"pino-pretty": "^13.1.1",
|
|
52
51
|
"xstate": "^5.23.0",
|
|
53
52
|
"zod": "3.25.76",
|
|
54
|
-
"@agiflowai/aicode-utils": "1.0.
|
|
55
|
-
"@agiflowai/coding-agent-bridge": "1.0.
|
|
53
|
+
"@agiflowai/aicode-utils": "1.0.4",
|
|
54
|
+
"@agiflowai/coding-agent-bridge": "1.0.5"
|
|
56
55
|
},
|
|
57
56
|
"devDependencies": {
|
|
58
57
|
"@types/express": "^5.0.0",
|
|
59
|
-
"@types/fs-extra": "^11.0.4",
|
|
60
58
|
"@types/js-yaml": "^4.0.9",
|
|
61
59
|
"@types/node": "^22.0.0",
|
|
62
60
|
"tsdown": "^0.16.4",
|