@agiflowai/aicode-toolkit 0.6.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/LICENSE +661 -0
- package/README.md +151 -0
- package/dist/cli.cjs +732 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +727 -0
- package/dist/index.cjs +17 -0
- package/dist/index.d.cts +282 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.js +4 -0
- package/dist/mcp-Bdxvi2Ej.cjs +4 -0
- package/dist/mcp-BmhiAfeF.js +47 -0
- package/dist/mcp-CZIiB-6Y.js +3 -0
- package/dist/mcp-Dwt8nYQV.cjs +65 -0
- package/dist/services-DNldrNnu.js +739 -0
- package/dist/services-s1vmufE4.cjs +859 -0
- package/package.json +85 -0
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const require_services = require('./services-s1vmufE4.cjs');
|
|
3
|
+
const require_mcp = require('./mcp-Dwt8nYQV.cjs');
|
|
4
|
+
let commander = require("commander");
|
|
5
|
+
commander = require_services.__toESM(commander);
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_services.__toESM(node_path);
|
|
8
|
+
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
9
|
+
__agiflowai_aicode_utils = require_services.__toESM(__agiflowai_aicode_utils);
|
|
10
|
+
let fs_extra = require("fs-extra");
|
|
11
|
+
fs_extra = require_services.__toESM(fs_extra);
|
|
12
|
+
let __inquirer_prompts = require("@inquirer/prompts");
|
|
13
|
+
__inquirer_prompts = require_services.__toESM(__inquirer_prompts);
|
|
14
|
+
let xstate = require("xstate");
|
|
15
|
+
xstate = require_services.__toESM(xstate);
|
|
16
|
+
|
|
17
|
+
//#region package.json
|
|
18
|
+
var name = "@agiflowai/aicode-toolkit";
|
|
19
|
+
var description = "AI-powered code toolkit CLI for scaffolding, architecture management, and development workflows";
|
|
20
|
+
var version = "0.6.0";
|
|
21
|
+
var license = "AGPL-3.0";
|
|
22
|
+
var author = "AgiflowIO";
|
|
23
|
+
var repository = {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/AgiFlow/aicode-toolkit.git",
|
|
26
|
+
"directory": "apps/aicode-toolkit"
|
|
27
|
+
};
|
|
28
|
+
var homepage = "https://github.com/AgiFlow/aicode-toolkit#readme";
|
|
29
|
+
var bugs = { "url": "https://github.com/AgiFlow/aicode-toolkit/issues" };
|
|
30
|
+
var keywords = [
|
|
31
|
+
"mcp",
|
|
32
|
+
"model-context-protocol",
|
|
33
|
+
"scaffold",
|
|
34
|
+
"boilerplate",
|
|
35
|
+
"template",
|
|
36
|
+
"code-generation",
|
|
37
|
+
"nextjs",
|
|
38
|
+
"react",
|
|
39
|
+
"vite"
|
|
40
|
+
];
|
|
41
|
+
var bin = { "aicode": "./dist/cli.cjs" };
|
|
42
|
+
var main$1 = "./dist/index.cjs";
|
|
43
|
+
var types = "./dist/index.d.cts";
|
|
44
|
+
var module$1 = "./dist/index.js";
|
|
45
|
+
var files = ["dist", "README.md"];
|
|
46
|
+
var scripts = {
|
|
47
|
+
"dev": "node --loader ts-node/esm src/cli.ts",
|
|
48
|
+
"build": "tsdown",
|
|
49
|
+
"test": "vitest --run",
|
|
50
|
+
"typecheck": "tsc --noEmit"
|
|
51
|
+
};
|
|
52
|
+
var dependencies = {
|
|
53
|
+
"@agiflowai/aicode-utils": "workspace:*",
|
|
54
|
+
"@agiflowai/coding-agent-bridge": "workspace:*",
|
|
55
|
+
"@composio/json-schema-to-zod": "0.1.15",
|
|
56
|
+
"@inquirer/prompts": "^7.8.6",
|
|
57
|
+
"@modelcontextprotocol/sdk": "1.19.1",
|
|
58
|
+
"chalk": "5.6.2",
|
|
59
|
+
"commander": "14.0.1",
|
|
60
|
+
"execa": "^9.5.2",
|
|
61
|
+
"express": "^4.21.2",
|
|
62
|
+
"fs-extra": "11.3.2",
|
|
63
|
+
"gradient-string": "^3.0.0",
|
|
64
|
+
"js-yaml": "4.1.0",
|
|
65
|
+
"liquidjs": "10.21.1",
|
|
66
|
+
"pino": "^10.0.0",
|
|
67
|
+
"pino-pretty": "^13.1.1",
|
|
68
|
+
"xstate": "^5.23.0",
|
|
69
|
+
"zod": "3.25.76"
|
|
70
|
+
};
|
|
71
|
+
var devDependencies = {
|
|
72
|
+
"@types/express": "^5.0.0",
|
|
73
|
+
"@types/fs-extra": "^11.0.4",
|
|
74
|
+
"@types/js-yaml": "^4.0.9",
|
|
75
|
+
"@types/node": "^22.0.0",
|
|
76
|
+
"tsdown": "^0.15.6",
|
|
77
|
+
"typescript": "5.9.3"
|
|
78
|
+
};
|
|
79
|
+
var publishConfig = { "access": "public" };
|
|
80
|
+
var type = "module";
|
|
81
|
+
var exports$1 = {
|
|
82
|
+
".": {
|
|
83
|
+
"import": "./dist/index.js",
|
|
84
|
+
"require": "./dist/index.cjs"
|
|
85
|
+
},
|
|
86
|
+
"./cli": {
|
|
87
|
+
"import": "./dist/cli.js",
|
|
88
|
+
"require": "./dist/cli.cjs"
|
|
89
|
+
},
|
|
90
|
+
"./package.json": "./package.json"
|
|
91
|
+
};
|
|
92
|
+
var package_default = {
|
|
93
|
+
name,
|
|
94
|
+
description,
|
|
95
|
+
version,
|
|
96
|
+
license,
|
|
97
|
+
author,
|
|
98
|
+
repository,
|
|
99
|
+
homepage,
|
|
100
|
+
bugs,
|
|
101
|
+
keywords,
|
|
102
|
+
bin,
|
|
103
|
+
main: main$1,
|
|
104
|
+
types,
|
|
105
|
+
module: module$1,
|
|
106
|
+
files,
|
|
107
|
+
scripts,
|
|
108
|
+
dependencies,
|
|
109
|
+
devDependencies,
|
|
110
|
+
publishConfig,
|
|
111
|
+
type,
|
|
112
|
+
exports: exports$1
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/commands/add.ts
|
|
117
|
+
/**
|
|
118
|
+
* Add command - add a template to templates folder
|
|
119
|
+
*/
|
|
120
|
+
const addCommand = new commander.Command("add").description("Add a template to templates folder").requiredOption("--name <name>", "Template name").requiredOption("--url <url>", "URL of the template repository to download").option("--path <path>", "Override templates folder path (uses toolkit.yaml config by default)").option("--type <type>", "Template type: boilerplate or scaffold", "boilerplate").action(async (options) => {
|
|
121
|
+
try {
|
|
122
|
+
const templatesPath = options.path ? node_path.default.resolve(options.path) : await __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPath();
|
|
123
|
+
const templateType = options.type.toLowerCase();
|
|
124
|
+
const templateName = options.name;
|
|
125
|
+
const templateUrl = options.url;
|
|
126
|
+
if (templateType !== "boilerplate" && templateType !== "scaffold") {
|
|
127
|
+
__agiflowai_aicode_utils.messages.error("Invalid template type. Use: boilerplate or scaffold");
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const targetFolder = node_path.default.join(templatesPath, `${templateType}s`, templateName);
|
|
131
|
+
if (await fs_extra.pathExists(targetFolder)) {
|
|
132
|
+
__agiflowai_aicode_utils.messages.error(`Template '${templateName}' already exists at ${targetFolder}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
__agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.download} Downloading template '${templateName}' from ${templateUrl}...`);
|
|
136
|
+
await fs_extra.ensureDir(node_path.default.dirname(targetFolder));
|
|
137
|
+
const parsedUrl = require_services.parseGitHubUrl(templateUrl);
|
|
138
|
+
try {
|
|
139
|
+
if (parsedUrl.isSubdirectory && parsedUrl.branch && parsedUrl.subdirectory) {
|
|
140
|
+
__agiflowai_aicode_utils.print.info(`${__agiflowai_aicode_utils.icons.folder} Detected subdirectory: ${parsedUrl.subdirectory} (branch: ${parsedUrl.branch})`);
|
|
141
|
+
await require_services.cloneSubdirectory(parsedUrl.repoUrl, parsedUrl.branch, parsedUrl.subdirectory, targetFolder);
|
|
142
|
+
} else await require_services.cloneRepository(parsedUrl.repoUrl, targetFolder);
|
|
143
|
+
__agiflowai_aicode_utils.messages.success(`Template '${templateName}' added successfully!`);
|
|
144
|
+
__agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.folder} Template location:`);
|
|
145
|
+
__agiflowai_aicode_utils.print.indent(targetFolder);
|
|
146
|
+
const configFiles = [node_path.default.join(targetFolder, "boilerplate.yaml"), node_path.default.join(targetFolder, "scaffold.yaml")];
|
|
147
|
+
let hasConfig = false;
|
|
148
|
+
for (const configFile of configFiles) if (await fs_extra.pathExists(configFile)) {
|
|
149
|
+
__agiflowai_aicode_utils.print.header(`\n${__agiflowai_aicode_utils.icons.config} Configuration file found:`);
|
|
150
|
+
__agiflowai_aicode_utils.print.indent(node_path.default.basename(configFile));
|
|
151
|
+
hasConfig = true;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
if (!hasConfig) {
|
|
155
|
+
__agiflowai_aicode_utils.messages.warning("Warning: No configuration file found (boilerplate.yaml or scaffold.yaml)");
|
|
156
|
+
__agiflowai_aicode_utils.print.indent("You may need to create one manually.");
|
|
157
|
+
}
|
|
158
|
+
__agiflowai_aicode_utils.sections.nextSteps([`Review the template in ${targetFolder}`, `Test it with: scaffold-mcp ${templateType} list`]);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (error.message.includes("not found") || error.message.includes("command not found")) __agiflowai_aicode_utils.messages.error("git command not found. Please install git first.");
|
|
161
|
+
else if (error.message.includes("Authentication failed")) __agiflowai_aicode_utils.messages.error("Authentication failed. Make sure you have access to the repository.");
|
|
162
|
+
else if (error.message.includes("Repository not found")) __agiflowai_aicode_utils.messages.error("Repository not found. Check the URL and try again.");
|
|
163
|
+
else __agiflowai_aicode_utils.messages.error("Failed to clone repository:", error);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
__agiflowai_aicode_utils.messages.error("Error adding template:", error);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/states/init-machine.ts
|
|
174
|
+
/**
|
|
175
|
+
* Init command state machine
|
|
176
|
+
* Pure declarative state machine definition
|
|
177
|
+
* Actors are provided externally for better separation of concerns
|
|
178
|
+
*/
|
|
179
|
+
const initMachine = (0, xstate.createMachine)({
|
|
180
|
+
id: "init",
|
|
181
|
+
types: {},
|
|
182
|
+
initial: "displayingBanner",
|
|
183
|
+
context: ({ input: input$1 }) => ({
|
|
184
|
+
workspaceRoot: void 0,
|
|
185
|
+
projectName: void 0,
|
|
186
|
+
projectType: void 0,
|
|
187
|
+
projectPath: void 0,
|
|
188
|
+
repositoryExists: false,
|
|
189
|
+
detectionConfidence: void 0,
|
|
190
|
+
detectionIndicators: void 0,
|
|
191
|
+
templatesPath: void 0,
|
|
192
|
+
tmpTemplatesPath: void 0,
|
|
193
|
+
selectedTemplates: void 0,
|
|
194
|
+
selectedMcpServers: void 0,
|
|
195
|
+
detectedCodingAgent: void 0,
|
|
196
|
+
codingAgent: void 0,
|
|
197
|
+
options: input$1.options,
|
|
198
|
+
error: void 0
|
|
199
|
+
}),
|
|
200
|
+
states: {
|
|
201
|
+
displayingBanner: { invoke: {
|
|
202
|
+
src: "displayBanner",
|
|
203
|
+
onDone: { target: "checkingWorkspace" }
|
|
204
|
+
} },
|
|
205
|
+
checkingWorkspace: { invoke: {
|
|
206
|
+
src: "checkWorkspaceExists",
|
|
207
|
+
onDone: [{
|
|
208
|
+
target: "detectingProjectType",
|
|
209
|
+
guard: ({ event }) => event.output.exists === true,
|
|
210
|
+
actions: (0, xstate.assign)({
|
|
211
|
+
workspaceRoot: ({ event }) => event.output.workspaceRoot,
|
|
212
|
+
repositoryExists: () => true
|
|
213
|
+
})
|
|
214
|
+
}, {
|
|
215
|
+
target: "creatingNewProject",
|
|
216
|
+
guard: ({ event }) => event.output.exists === false,
|
|
217
|
+
actions: (0, xstate.assign)({ repositoryExists: () => false })
|
|
218
|
+
}]
|
|
219
|
+
} },
|
|
220
|
+
detectingProjectType: { invoke: {
|
|
221
|
+
src: "detectProjectType",
|
|
222
|
+
input: ({ context }) => ({ workspaceRoot: context.workspaceRoot }),
|
|
223
|
+
onDone: [{
|
|
224
|
+
target: "checkingSkipTemplates",
|
|
225
|
+
guard: ({ event }) => event.output.confidence === "high",
|
|
226
|
+
actions: (0, xstate.assign)({
|
|
227
|
+
projectType: ({ event }) => event.output.projectType,
|
|
228
|
+
detectionConfidence: ({ event }) => event.output.confidence,
|
|
229
|
+
detectionIndicators: ({ event }) => event.output.indicators
|
|
230
|
+
})
|
|
231
|
+
}, {
|
|
232
|
+
target: "promptingProjectType",
|
|
233
|
+
actions: (0, xstate.assign)({
|
|
234
|
+
detectionConfidence: ({ event }) => event.output.confidence,
|
|
235
|
+
detectionIndicators: ({ event }) => event.output.indicators
|
|
236
|
+
})
|
|
237
|
+
}],
|
|
238
|
+
onError: {
|
|
239
|
+
target: "failed",
|
|
240
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
241
|
+
}
|
|
242
|
+
} },
|
|
243
|
+
promptingProjectType: { invoke: {
|
|
244
|
+
src: "promptProjectType",
|
|
245
|
+
input: ({ context }) => ({
|
|
246
|
+
providedProjectType: context.options.projectType,
|
|
247
|
+
detectionIndicators: context.detectionIndicators
|
|
248
|
+
}),
|
|
249
|
+
onDone: {
|
|
250
|
+
target: "checkingSkipTemplates",
|
|
251
|
+
actions: (0, xstate.assign)({ projectType: ({ event }) => event.output })
|
|
252
|
+
},
|
|
253
|
+
onError: {
|
|
254
|
+
target: "failed",
|
|
255
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
256
|
+
}
|
|
257
|
+
} },
|
|
258
|
+
creatingNewProject: {
|
|
259
|
+
initial: "promptingProjectName",
|
|
260
|
+
states: {
|
|
261
|
+
promptingProjectName: { invoke: {
|
|
262
|
+
src: "promptProjectName",
|
|
263
|
+
input: ({ context }) => ({ providedName: context.options.name }),
|
|
264
|
+
onDone: {
|
|
265
|
+
target: "creatingProjectDirectory",
|
|
266
|
+
actions: (0, xstate.assign)({ projectName: ({ event }) => event.output })
|
|
267
|
+
},
|
|
268
|
+
onError: {
|
|
269
|
+
target: "#init.failed",
|
|
270
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
271
|
+
}
|
|
272
|
+
} },
|
|
273
|
+
creatingProjectDirectory: { invoke: {
|
|
274
|
+
src: "createProjectDirectory",
|
|
275
|
+
input: ({ context }) => ({ projectName: context.projectName }),
|
|
276
|
+
onDone: {
|
|
277
|
+
target: "promptingGitSetup",
|
|
278
|
+
actions: (0, xstate.assign)({
|
|
279
|
+
projectPath: ({ event }) => event.output.projectPath,
|
|
280
|
+
workspaceRoot: ({ event }) => event.output.projectPath
|
|
281
|
+
})
|
|
282
|
+
},
|
|
283
|
+
onError: {
|
|
284
|
+
target: "#init.failed",
|
|
285
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
286
|
+
}
|
|
287
|
+
} },
|
|
288
|
+
promptingGitSetup: { invoke: {
|
|
289
|
+
src: "promptGitSetup",
|
|
290
|
+
input: ({ context }) => ({ projectPath: context.projectPath }),
|
|
291
|
+
onDone: { target: "promptingProjectType" },
|
|
292
|
+
onError: {
|
|
293
|
+
target: "#init.failed",
|
|
294
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
295
|
+
}
|
|
296
|
+
} },
|
|
297
|
+
promptingProjectType: { invoke: {
|
|
298
|
+
src: "promptProjectType",
|
|
299
|
+
input: ({ context }) => ({ providedProjectType: context.options.projectType }),
|
|
300
|
+
onDone: {
|
|
301
|
+
target: "#init.checkingSkipTemplates",
|
|
302
|
+
actions: (0, xstate.assign)({ projectType: ({ event }) => event.output })
|
|
303
|
+
},
|
|
304
|
+
onError: {
|
|
305
|
+
target: "#init.failed",
|
|
306
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
307
|
+
}
|
|
308
|
+
} }
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
checkingSkipTemplates: { always: [{
|
|
312
|
+
target: "promptingMcpSelection",
|
|
313
|
+
guard: ({ context }) => !context.options.skipTemplates
|
|
314
|
+
}, { target: "checkingSkipMcp" }] },
|
|
315
|
+
promptingMcpSelection: { invoke: {
|
|
316
|
+
src: "promptMcpSelection",
|
|
317
|
+
onDone: {
|
|
318
|
+
target: "downloadingTemplates",
|
|
319
|
+
actions: (0, xstate.assign)({ selectedMcpServers: ({ event }) => event.output })
|
|
320
|
+
},
|
|
321
|
+
onError: {
|
|
322
|
+
target: "failed",
|
|
323
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
324
|
+
}
|
|
325
|
+
} },
|
|
326
|
+
downloadingTemplates: { invoke: {
|
|
327
|
+
src: "downloadTemplates",
|
|
328
|
+
onDone: {
|
|
329
|
+
target: "listingTemplates",
|
|
330
|
+
actions: (0, xstate.assign)({ tmpTemplatesPath: ({ event }) => event.output })
|
|
331
|
+
},
|
|
332
|
+
onError: {
|
|
333
|
+
target: "failed",
|
|
334
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
335
|
+
}
|
|
336
|
+
} },
|
|
337
|
+
listingTemplates: { invoke: {
|
|
338
|
+
src: "listTemplates",
|
|
339
|
+
input: ({ context }) => ({ tmpTemplatesPath: context.tmpTemplatesPath }),
|
|
340
|
+
onDone: { target: "promptingTemplateSelection" },
|
|
341
|
+
onError: {
|
|
342
|
+
target: "failed",
|
|
343
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
344
|
+
}
|
|
345
|
+
} },
|
|
346
|
+
promptingTemplateSelection: { invoke: {
|
|
347
|
+
src: "promptTemplateSelection",
|
|
348
|
+
input: ({ context }) => ({
|
|
349
|
+
tmpTemplatesPath: context.tmpTemplatesPath,
|
|
350
|
+
projectType: context.projectType
|
|
351
|
+
}),
|
|
352
|
+
onDone: {
|
|
353
|
+
target: "copyingTemplates",
|
|
354
|
+
actions: (0, xstate.assign)({ selectedTemplates: ({ event }) => event.output })
|
|
355
|
+
},
|
|
356
|
+
onError: {
|
|
357
|
+
target: "failed",
|
|
358
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
359
|
+
}
|
|
360
|
+
} },
|
|
361
|
+
copyingTemplates: { invoke: {
|
|
362
|
+
src: "copyTemplates",
|
|
363
|
+
input: ({ context }) => ({
|
|
364
|
+
tmpTemplatesPath: context.tmpTemplatesPath,
|
|
365
|
+
workspaceRoot: context.workspaceRoot,
|
|
366
|
+
selectedTemplates: context.selectedTemplates,
|
|
367
|
+
projectType: context.projectType,
|
|
368
|
+
selectedMcpServers: context.selectedMcpServers
|
|
369
|
+
}),
|
|
370
|
+
onDone: {
|
|
371
|
+
target: "creatingConfig",
|
|
372
|
+
actions: (0, xstate.assign)({ templatesPath: ({ event }) => event.output })
|
|
373
|
+
},
|
|
374
|
+
onError: {
|
|
375
|
+
target: "failed",
|
|
376
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
377
|
+
}
|
|
378
|
+
} },
|
|
379
|
+
creatingConfig: { invoke: {
|
|
380
|
+
src: "createConfig",
|
|
381
|
+
input: ({ context }) => ({
|
|
382
|
+
workspaceRoot: context.workspaceRoot,
|
|
383
|
+
projectType: context.projectType,
|
|
384
|
+
selectedTemplates: context.selectedTemplates
|
|
385
|
+
}),
|
|
386
|
+
onDone: { target: "checkingSkipMcp" },
|
|
387
|
+
onError: {
|
|
388
|
+
target: "failed",
|
|
389
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
390
|
+
}
|
|
391
|
+
} },
|
|
392
|
+
checkingSkipMcp: { always: [{
|
|
393
|
+
target: "detectingCodingAgent",
|
|
394
|
+
guard: ({ context }) => !context.options.skipMcp
|
|
395
|
+
}, { target: "cleaningUp" }] },
|
|
396
|
+
detectingCodingAgent: { invoke: {
|
|
397
|
+
src: "detectCodingAgent",
|
|
398
|
+
input: ({ context }) => ({ workspaceRoot: context.workspaceRoot }),
|
|
399
|
+
onDone: {
|
|
400
|
+
target: "promptingCodingAgent",
|
|
401
|
+
actions: (0, xstate.assign)({ detectedCodingAgent: ({ event }) => event.output })
|
|
402
|
+
},
|
|
403
|
+
onError: {
|
|
404
|
+
target: "failed",
|
|
405
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
406
|
+
}
|
|
407
|
+
} },
|
|
408
|
+
promptingCodingAgent: { invoke: {
|
|
409
|
+
src: "promptCodingAgent",
|
|
410
|
+
input: ({ context }) => ({ detectedAgent: context.detectedCodingAgent }),
|
|
411
|
+
onDone: {
|
|
412
|
+
target: "configuringMCP",
|
|
413
|
+
actions: (0, xstate.assign)({ codingAgent: ({ event }) => event.output })
|
|
414
|
+
},
|
|
415
|
+
onError: {
|
|
416
|
+
target: "failed",
|
|
417
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
418
|
+
}
|
|
419
|
+
} },
|
|
420
|
+
configuringMCP: { invoke: {
|
|
421
|
+
src: "configureMCP",
|
|
422
|
+
input: ({ context }) => ({
|
|
423
|
+
workspaceRoot: context.workspaceRoot,
|
|
424
|
+
codingAgent: context.codingAgent
|
|
425
|
+
}),
|
|
426
|
+
onDone: { target: "cleaningUp" },
|
|
427
|
+
onError: {
|
|
428
|
+
target: "failed",
|
|
429
|
+
actions: (0, xstate.assign)({ error: ({ event }) => event.error })
|
|
430
|
+
}
|
|
431
|
+
} },
|
|
432
|
+
cleaningUp: { invoke: {
|
|
433
|
+
src: "cleanup",
|
|
434
|
+
input: ({ context }) => ({ tmpTemplatesPath: context.tmpTemplatesPath }),
|
|
435
|
+
onDone: { target: "completed" },
|
|
436
|
+
onError: { target: "completed" }
|
|
437
|
+
} },
|
|
438
|
+
completed: { type: "final" },
|
|
439
|
+
failed: { type: "final" }
|
|
440
|
+
}
|
|
441
|
+
}, { guards: {} });
|
|
442
|
+
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/commands/init.ts
|
|
445
|
+
const DEFAULT_TEMPLATE_REPO = {
|
|
446
|
+
owner: "AgiFlow",
|
|
447
|
+
repo: "aicode-toolkit",
|
|
448
|
+
branch: "main",
|
|
449
|
+
path: "templates"
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* Actor implementations for the init V2 state machine
|
|
453
|
+
*/
|
|
454
|
+
const initActors = {
|
|
455
|
+
displayBanner: (0, xstate.fromPromise)(async () => {
|
|
456
|
+
require_services.displayBanner();
|
|
457
|
+
}),
|
|
458
|
+
checkWorkspaceExists: (0, xstate.fromPromise)(async () => {
|
|
459
|
+
const workspaceRoot = await require_services.findWorkspaceRoot();
|
|
460
|
+
if (workspaceRoot) {
|
|
461
|
+
__agiflowai_aicode_utils.print.info(`Found workspace at: ${workspaceRoot}`);
|
|
462
|
+
return {
|
|
463
|
+
exists: true,
|
|
464
|
+
workspaceRoot
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
return { exists: false };
|
|
468
|
+
}),
|
|
469
|
+
detectProjectType: (0, xstate.fromPromise)(async ({ input: input$1 }) => {
|
|
470
|
+
__agiflowai_aicode_utils.print.info("\nDetecting project type...");
|
|
471
|
+
const nxJsonPath = node_path.default.join(input$1.workspaceRoot, "nx.json");
|
|
472
|
+
const lernaJsonPath = node_path.default.join(input$1.workspaceRoot, "lerna.json");
|
|
473
|
+
const pnpmWorkspacePath = node_path.default.join(input$1.workspaceRoot, "pnpm-workspace.yaml");
|
|
474
|
+
const turboJsonPath = node_path.default.join(input$1.workspaceRoot, "turbo.json");
|
|
475
|
+
const indicators = [];
|
|
476
|
+
let projectType;
|
|
477
|
+
let confidence = "low";
|
|
478
|
+
if (await fs_extra.pathExists(nxJsonPath)) {
|
|
479
|
+
indicators.push("nx.json found");
|
|
480
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOREPO;
|
|
481
|
+
confidence = "high";
|
|
482
|
+
}
|
|
483
|
+
if (await fs_extra.pathExists(lernaJsonPath)) {
|
|
484
|
+
indicators.push("lerna.json found");
|
|
485
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOREPO;
|
|
486
|
+
confidence = "high";
|
|
487
|
+
}
|
|
488
|
+
if (await fs_extra.pathExists(pnpmWorkspacePath)) {
|
|
489
|
+
indicators.push("pnpm-workspace.yaml found");
|
|
490
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOREPO;
|
|
491
|
+
confidence = "high";
|
|
492
|
+
}
|
|
493
|
+
if (await fs_extra.pathExists(turboJsonPath)) {
|
|
494
|
+
indicators.push("turbo.json found");
|
|
495
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOREPO;
|
|
496
|
+
confidence = "high";
|
|
497
|
+
}
|
|
498
|
+
const packageJsonPath = node_path.default.join(input$1.workspaceRoot, "package.json");
|
|
499
|
+
if (await fs_extra.pathExists(packageJsonPath)) {
|
|
500
|
+
if ((await fs_extra.readJson(packageJsonPath)).workspaces) {
|
|
501
|
+
indicators.push("package.json with workspaces found");
|
|
502
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOREPO;
|
|
503
|
+
if (confidence !== "high") confidence = "medium";
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const toolkitYamlPath = node_path.default.join(input$1.workspaceRoot, "toolkit.yaml");
|
|
507
|
+
if (await fs_extra.pathExists(toolkitYamlPath)) {
|
|
508
|
+
const toolkitConfig = await __agiflowai_aicode_utils.TemplatesManagerService.readToolkitConfig(input$1.workspaceRoot);
|
|
509
|
+
if (toolkitConfig?.projectType) {
|
|
510
|
+
indicators.push(`toolkit.yaml specifies ${toolkitConfig.projectType}`);
|
|
511
|
+
projectType = toolkitConfig.projectType;
|
|
512
|
+
confidence = "high";
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (!projectType) {
|
|
516
|
+
projectType = __agiflowai_aicode_utils.ProjectType.MONOLITH;
|
|
517
|
+
indicators.push("No monorepo indicators found, assuming monolith");
|
|
518
|
+
confidence = "low";
|
|
519
|
+
}
|
|
520
|
+
if (confidence === "high") __agiflowai_aicode_utils.print.success(`Detected ${projectType} project (high confidence)`);
|
|
521
|
+
return {
|
|
522
|
+
projectType,
|
|
523
|
+
confidence,
|
|
524
|
+
indicators
|
|
525
|
+
};
|
|
526
|
+
}),
|
|
527
|
+
promptProjectType: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
528
|
+
if (actorInput.providedProjectType) {
|
|
529
|
+
const projectType = actorInput.providedProjectType;
|
|
530
|
+
__agiflowai_aicode_utils.print.info(`Project type: ${projectType}`);
|
|
531
|
+
return projectType;
|
|
532
|
+
}
|
|
533
|
+
if (actorInput.detectionIndicators && actorInput.detectionIndicators.length > 0) {
|
|
534
|
+
__agiflowai_aicode_utils.print.info("\nDetection results:");
|
|
535
|
+
for (const indicator of actorInput.detectionIndicators) __agiflowai_aicode_utils.print.indent(`• ${indicator}`);
|
|
536
|
+
__agiflowai_aicode_utils.print.newline();
|
|
537
|
+
}
|
|
538
|
+
return await (0, __inquirer_prompts.select)({
|
|
539
|
+
message: "Select project type:",
|
|
540
|
+
choices: [{
|
|
541
|
+
name: "Monolith - Single application structure",
|
|
542
|
+
value: __agiflowai_aicode_utils.ProjectType.MONOLITH,
|
|
543
|
+
description: "Traditional single-application project structure"
|
|
544
|
+
}, {
|
|
545
|
+
name: "Monorepo - Multiple packages/apps in one repository",
|
|
546
|
+
value: __agiflowai_aicode_utils.ProjectType.MONOREPO,
|
|
547
|
+
description: "Multiple packages managed together (uses workspaces)"
|
|
548
|
+
}]
|
|
549
|
+
});
|
|
550
|
+
}),
|
|
551
|
+
promptProjectName: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
552
|
+
const newProjectService = new require_services.NewProjectService(actorInput.providedName, void 0);
|
|
553
|
+
const providedName = newProjectService.getProvidedName();
|
|
554
|
+
if (providedName) {
|
|
555
|
+
const trimmedName = providedName.trim();
|
|
556
|
+
const validationResult = newProjectService.validateProjectName(trimmedName);
|
|
557
|
+
if (validationResult !== true) throw new Error(validationResult);
|
|
558
|
+
__agiflowai_aicode_utils.print.info(`Project name: ${trimmedName}`);
|
|
559
|
+
return trimmedName;
|
|
560
|
+
}
|
|
561
|
+
return await (0, __inquirer_prompts.input)({
|
|
562
|
+
message: "Enter your project name:",
|
|
563
|
+
validate: (value) => newProjectService.validateProjectName(value)
|
|
564
|
+
});
|
|
565
|
+
}),
|
|
566
|
+
createProjectDirectory: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
567
|
+
const projectPath = node_path.default.join(process.cwd(), actorInput.projectName.trim());
|
|
568
|
+
await new require_services.NewProjectService(void 0, void 0).createProjectDirectory(projectPath, actorInput.projectName);
|
|
569
|
+
return { projectPath };
|
|
570
|
+
}),
|
|
571
|
+
promptGitSetup: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
572
|
+
const newProjectService = new require_services.NewProjectService(void 0, void 0);
|
|
573
|
+
if (await (0, __inquirer_prompts.confirm)({
|
|
574
|
+
message: "Do you have an existing Git repository you want to use?",
|
|
575
|
+
default: false
|
|
576
|
+
})) {
|
|
577
|
+
const repoUrl = await (0, __inquirer_prompts.input)({
|
|
578
|
+
message: "Enter Git repository URL:",
|
|
579
|
+
validate: (value) => newProjectService.validateRepositoryUrl(value)
|
|
580
|
+
});
|
|
581
|
+
await newProjectService.cloneExistingRepository(repoUrl.trim(), actorInput.projectPath);
|
|
582
|
+
} else if (await (0, __inquirer_prompts.confirm)({
|
|
583
|
+
message: "Initialize a new Git repository?",
|
|
584
|
+
default: true
|
|
585
|
+
})) await newProjectService.initializeGitRepository(actorInput.projectPath);
|
|
586
|
+
}),
|
|
587
|
+
promptMcpSelection: (0, xstate.fromPromise)(async () => {
|
|
588
|
+
return await (await import("@inquirer/prompts").then((m) => m.checkbox))({
|
|
589
|
+
message: "Select MCP servers to configure:",
|
|
590
|
+
choices: Object.values(require_mcp.MCPServer).map((server) => ({
|
|
591
|
+
name: require_mcp.MCP_SERVER_INFO[server].name,
|
|
592
|
+
value: server,
|
|
593
|
+
description: require_mcp.MCP_SERVER_INFO[server].description,
|
|
594
|
+
checked: true
|
|
595
|
+
})),
|
|
596
|
+
validate: (answer) => {
|
|
597
|
+
if (answer.length === 0) return "Please select at least one MCP server";
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
}),
|
|
602
|
+
downloadTemplates: (0, xstate.fromPromise)(async () => {
|
|
603
|
+
return await new require_services.TemplateSelectionService().downloadTemplatesToTmp(DEFAULT_TEMPLATE_REPO);
|
|
604
|
+
}),
|
|
605
|
+
listTemplates: (0, xstate.fromPromise)(async ({ input: input$1 }) => {
|
|
606
|
+
const templates = await new require_services.TemplateSelectionService(input$1.tmpTemplatesPath).listTemplates();
|
|
607
|
+
__agiflowai_aicode_utils.print.header("\nAvailable templates:");
|
|
608
|
+
for (const template of templates) __agiflowai_aicode_utils.print.item(`${template.name}${template.description ? ` - ${template.description}` : ""}`);
|
|
609
|
+
return templates;
|
|
610
|
+
}),
|
|
611
|
+
promptTemplateSelection: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
612
|
+
const templates = await new require_services.TemplateSelectionService(actorInput.tmpTemplatesPath).listTemplates();
|
|
613
|
+
if (templates.length === 0) throw new Error("No templates available");
|
|
614
|
+
if (actorInput.projectType === __agiflowai_aicode_utils.ProjectType.MONOLITH) return [await (0, __inquirer_prompts.select)({
|
|
615
|
+
message: "Select template (monolith allows only one):",
|
|
616
|
+
choices: templates.map((t) => ({
|
|
617
|
+
name: t.name,
|
|
618
|
+
value: t.name,
|
|
619
|
+
description: t.description
|
|
620
|
+
}))
|
|
621
|
+
})];
|
|
622
|
+
const selected = await (await import("@inquirer/prompts").then((m) => m.checkbox))({
|
|
623
|
+
message: "Select templates (use space to select, enter to confirm):",
|
|
624
|
+
choices: templates.map((t) => ({
|
|
625
|
+
name: t.name,
|
|
626
|
+
value: t.name,
|
|
627
|
+
description: t.description,
|
|
628
|
+
checked: true
|
|
629
|
+
}))
|
|
630
|
+
});
|
|
631
|
+
if (selected.length === 0) throw new Error("Please select at least one template");
|
|
632
|
+
return selected;
|
|
633
|
+
}),
|
|
634
|
+
copyTemplates: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
635
|
+
const templateSelectionService = new require_services.TemplateSelectionService(actorInput.tmpTemplatesPath);
|
|
636
|
+
const templatesPath = node_path.default.join(actorInput.workspaceRoot, "templates");
|
|
637
|
+
await templateSelectionService.copyTemplates(actorInput.selectedTemplates, templatesPath, actorInput.projectType, actorInput.selectedMcpServers);
|
|
638
|
+
return templatesPath;
|
|
639
|
+
}),
|
|
640
|
+
createConfig: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
641
|
+
if (actorInput.projectType === __agiflowai_aicode_utils.ProjectType.MONOLITH) {
|
|
642
|
+
const toolkitConfig = {
|
|
643
|
+
version: "1.0",
|
|
644
|
+
templatesPath: "templates",
|
|
645
|
+
projectType: "monolith",
|
|
646
|
+
sourceTemplate: actorInput.selectedTemplates[0]
|
|
647
|
+
};
|
|
648
|
+
__agiflowai_aicode_utils.print.info("\nCreating toolkit.yaml...");
|
|
649
|
+
await __agiflowai_aicode_utils.TemplatesManagerService.writeToolkitConfig(toolkitConfig, actorInput.workspaceRoot);
|
|
650
|
+
__agiflowai_aicode_utils.print.success("toolkit.yaml created");
|
|
651
|
+
}
|
|
652
|
+
}),
|
|
653
|
+
detectCodingAgent: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
654
|
+
__agiflowai_aicode_utils.print.info("\nDetecting coding agent...");
|
|
655
|
+
const detectedAgent = await require_services.CodingAgentService.detectCodingAgent(actorInput.workspaceRoot);
|
|
656
|
+
if (detectedAgent) __agiflowai_aicode_utils.print.success(`Detected ${detectedAgent} in workspace`);
|
|
657
|
+
else __agiflowai_aicode_utils.print.info("No coding agent detected automatically");
|
|
658
|
+
return detectedAgent;
|
|
659
|
+
}),
|
|
660
|
+
promptCodingAgent: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
661
|
+
if (actorInput.detectedAgent) {
|
|
662
|
+
__agiflowai_aicode_utils.print.info(`Using detected coding agent: ${actorInput.detectedAgent}`);
|
|
663
|
+
return actorInput.detectedAgent;
|
|
664
|
+
}
|
|
665
|
+
return await (0, __inquirer_prompts.select)({
|
|
666
|
+
message: "Select coding agent for MCP configuration:",
|
|
667
|
+
choices: require_services.CodingAgentService.getAvailableAgents().map((agent) => ({
|
|
668
|
+
name: agent.name,
|
|
669
|
+
value: agent.value,
|
|
670
|
+
description: agent.description
|
|
671
|
+
}))
|
|
672
|
+
});
|
|
673
|
+
}),
|
|
674
|
+
configureMCP: (0, xstate.fromPromise)(async ({ input: actorInput }) => {
|
|
675
|
+
await new require_services.CodingAgentService(actorInput.workspaceRoot).setupMCP(actorInput.codingAgent);
|
|
676
|
+
}),
|
|
677
|
+
cleanup: (0, xstate.fromPromise)(async ({ input: input$1 }) => {
|
|
678
|
+
if (input$1.tmpTemplatesPath) await new require_services.TemplateSelectionService(input$1.tmpTemplatesPath).cleanup();
|
|
679
|
+
})
|
|
680
|
+
};
|
|
681
|
+
/**
|
|
682
|
+
* Init command - improved V2 implementation
|
|
683
|
+
*/
|
|
684
|
+
const initCommand = new commander.Command("init").description("Initialize project with templates and MCP configuration").option("--name <name>", "Project name (for new projects)").option("--project-type <type>", "Project type: monolith or monorepo (for new projects)").option("--skip-templates", "Skip template download and selection").option("--skip-mcp", "Skip MCP configuration").action(async (options) => {
|
|
685
|
+
try {
|
|
686
|
+
const actor = (0, xstate.createActor)(initMachine.provide({ actors: initActors }), { input: { options: {
|
|
687
|
+
name: options.name,
|
|
688
|
+
projectType: options.projectType,
|
|
689
|
+
skipTemplates: options.skipTemplates || false,
|
|
690
|
+
skipMcp: options.skipMcp || false
|
|
691
|
+
} } });
|
|
692
|
+
actor.start();
|
|
693
|
+
await new Promise((resolve, reject) => {
|
|
694
|
+
const subscription = actor.subscribe((state) => {
|
|
695
|
+
if (state.matches("completed")) {
|
|
696
|
+
subscription.unsubscribe();
|
|
697
|
+
resolve();
|
|
698
|
+
} else if (state.matches("failed")) {
|
|
699
|
+
subscription.unsubscribe();
|
|
700
|
+
reject(new Error(state.context.error?.message || "Unknown error"));
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
const { templatesPath, projectType } = actor.getSnapshot().context;
|
|
705
|
+
__agiflowai_aicode_utils.print.header("\nSetup Complete!");
|
|
706
|
+
if (templatesPath) __agiflowai_aicode_utils.print.info(`Templates location: ${templatesPath}`);
|
|
707
|
+
if (projectType) __agiflowai_aicode_utils.print.info(`Project type: ${projectType}`);
|
|
708
|
+
const gradient = await import("gradient-string");
|
|
709
|
+
__agiflowai_aicode_utils.print.newline();
|
|
710
|
+
console.log(gradient.default.pastel.multiline("🎉 Congratulations! Your project is ready to go!"));
|
|
711
|
+
__agiflowai_aicode_utils.print.newline();
|
|
712
|
+
} catch (error) {
|
|
713
|
+
__agiflowai_aicode_utils.print.error(`\nError: ${error.message}`);
|
|
714
|
+
process.exit(1);
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
//#endregion
|
|
719
|
+
//#region src/cli.ts
|
|
720
|
+
/**
|
|
721
|
+
* Main entry point
|
|
722
|
+
*/
|
|
723
|
+
async function main() {
|
|
724
|
+
const program = new commander.Command();
|
|
725
|
+
program.name("aicode").description("AI-powered code toolkit CLI for scaffolding, architecture management, and development workflows").version(package_default.version);
|
|
726
|
+
program.addCommand(initCommand);
|
|
727
|
+
program.addCommand(addCommand);
|
|
728
|
+
await program.parseAsync(process.argv);
|
|
729
|
+
}
|
|
730
|
+
main();
|
|
731
|
+
|
|
732
|
+
//#endregion
|