@aventara/cli 1.0.0-rc.0 → 1.0.0-rc.2
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/CHANGELOG.md +260 -0
- package/README.md +61 -42
- package/dist/apply/conflict.confirmer.js +4 -4
- package/dist/cli.js +24 -14
- package/dist/command/command.parser.js +44 -10
- package/dist/plan/project.planner.js +11 -4
- package/dist/project/project.inspector.js +8 -8
- package/dist/run/init.orchestrator.js +8 -8
- package/dist/run/new.orchestrator.js +5 -5
- package/dist/run/skill.orchestrator.js +54 -0
- package/dist/skill/agent-skill.generated.js +7 -0
- package/dist/skill/agent-skill.planner.js +116 -0
- package/dist/templates/docs.links.js +2 -1
- package/dist/templates/prisma7/prisma7.templates.js +31 -8
- package/dist/templates/template.registry.js +1 -1
- package/dist/wizard/answer.resolver.js +5 -5
- package/dist/wizard/readline.prompter.js +3 -3
- package/dist/wizard/wizard.questions.js +9 -9
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export class
|
|
3
|
-
name = "
|
|
1
|
+
import { AvWizardAnswerError } from "./wizard.questions.js";
|
|
2
|
+
export class AvUnansweredQuestionsError extends Error {
|
|
3
|
+
name = "AvUnansweredQuestionsError";
|
|
4
4
|
}
|
|
5
5
|
function flagSpelling(question, context) {
|
|
6
6
|
if (!question.flag.startsWith("--")) {
|
|
@@ -41,7 +41,7 @@ async function prompt(question, context, prompter) {
|
|
|
41
41
|
return question.parse(raw, context);
|
|
42
42
|
}
|
|
43
43
|
catch (error) {
|
|
44
|
-
if (!(error instanceof
|
|
44
|
+
if (!(error instanceof AvWizardAnswerError)) {
|
|
45
45
|
throw error;
|
|
46
46
|
}
|
|
47
47
|
prompter.say(`${error.message}.`);
|
|
@@ -90,7 +90,7 @@ export async function resolveAnswers(questions, sources) {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
if (missing.length > 0) {
|
|
93
|
-
throw new
|
|
93
|
+
throw new AvUnansweredQuestionsError(unansweredSentence(missing, sources.yes));
|
|
94
94
|
}
|
|
95
95
|
return answered;
|
|
96
96
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
|
-
export class
|
|
3
|
-
name = "
|
|
2
|
+
export class AvWizardCancelledError extends Error {
|
|
3
|
+
name = "AvWizardCancelledError";
|
|
4
4
|
}
|
|
5
5
|
export function createReadlinePrompter(streams) {
|
|
6
6
|
let session;
|
|
7
7
|
let ended = false;
|
|
8
8
|
const lines = [];
|
|
9
9
|
const waiting = [];
|
|
10
|
-
const cancelled = () => new
|
|
10
|
+
const cancelled = () => new AvWizardCancelledError("the wizard was closed before it was answered");
|
|
11
11
|
const open = () => {
|
|
12
12
|
if (session === undefined) {
|
|
13
13
|
session = createInterface({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { modulesProviding, } from "../project/service.detector.js";
|
|
2
2
|
export const PACKAGE_MANAGERS = ["npm", "pnpm"];
|
|
3
|
-
export class
|
|
4
|
-
name = "
|
|
3
|
+
export class AvWizardAnswerError extends Error {
|
|
4
|
+
name = "AvWizardAnswerError";
|
|
5
5
|
}
|
|
6
6
|
function ormLabel(entry) {
|
|
7
7
|
return `${entry.orm.label} ${entry.orm.major}`;
|
|
@@ -32,7 +32,7 @@ export const NAME_QUESTION = {
|
|
|
32
32
|
parse: (raw) => {
|
|
33
33
|
const name = raw.trim();
|
|
34
34
|
if (!NAME.test(name)) {
|
|
35
|
-
throw new
|
|
35
|
+
throw new AvWizardAnswerError(`${JSON.stringify(raw)} is not a project name: use letters, digits, ".", "_" and "-", starting with a letter or digit`);
|
|
36
36
|
}
|
|
37
37
|
return name;
|
|
38
38
|
},
|
|
@@ -52,7 +52,7 @@ export const ORM_QUESTION = {
|
|
|
52
52
|
const alias = raw.trim().toLowerCase();
|
|
53
53
|
const entry = context.catalog.find((candidate) => candidate.alias === alias);
|
|
54
54
|
if (entry === undefined) {
|
|
55
|
-
throw new
|
|
55
|
+
throw new AvWizardAnswerError(`there is no Aventara adapter for the ORM ${JSON.stringify(raw)}; ${ormAliasesSentence(context.catalog)}`);
|
|
56
56
|
}
|
|
57
57
|
return entry;
|
|
58
58
|
},
|
|
@@ -82,7 +82,7 @@ export const DB_QUESTION = {
|
|
|
82
82
|
const orm = requireOrm(context);
|
|
83
83
|
const db = raw.trim().toLowerCase();
|
|
84
84
|
if (!orm.providers.includes(db)) {
|
|
85
|
-
throw new
|
|
85
|
+
throw new AvWizardAnswerError(`the ${ormLabel(orm)} adapter does not support the database ${JSON.stringify(raw)}; choose ${orm.providers.join(" or ")}`);
|
|
86
86
|
}
|
|
87
87
|
return db;
|
|
88
88
|
},
|
|
@@ -98,7 +98,7 @@ export const PACKAGE_MANAGER_QUESTION = {
|
|
|
98
98
|
parse: (raw) => {
|
|
99
99
|
const manager = PACKAGE_MANAGERS.find((candidate) => candidate === raw.trim().toLowerCase());
|
|
100
100
|
if (manager === undefined) {
|
|
101
|
-
throw new
|
|
101
|
+
throw new AvWizardAnswerError(`${JSON.stringify(raw)} is not a supported package manager; choose ${PACKAGE_MANAGERS.join(" or ")}`);
|
|
102
102
|
}
|
|
103
103
|
return manager;
|
|
104
104
|
},
|
|
@@ -109,7 +109,7 @@ function reference(raw, flag) {
|
|
|
109
109
|
const exportName = raw.slice(hash + 1).trim();
|
|
110
110
|
const file = raw.slice(0, hash).trim().replace(/^\.\//, "");
|
|
111
111
|
if (hash <= 0 || !/^[A-Za-z_$][\w$]*$/.test(exportName)) {
|
|
112
|
-
throw new
|
|
112
|
+
throw new AvWizardAnswerError(`${flag} takes <path#Export>, a file and the name it exports, such as src/prisma.service.ts#PrismaService; got ${JSON.stringify(raw)}`);
|
|
113
113
|
}
|
|
114
114
|
return { file, exportName };
|
|
115
115
|
}
|
|
@@ -166,7 +166,7 @@ export const SERVICE_QUESTION = {
|
|
|
166
166
|
const options = serviceOptions(services);
|
|
167
167
|
const chosen = options.find((option) => option.file === wanted.file && option.exportName === wanted.exportName);
|
|
168
168
|
if (chosen === undefined) {
|
|
169
|
-
throw new
|
|
169
|
+
throw new AvWizardAnswerError(`${spelled(wanted)} is not a service found in src/ (a class extending ${services.clientClass}, or one holding it); found: ${options
|
|
170
170
|
.filter((option) => !option.isNew)
|
|
171
171
|
.map(spelled)
|
|
172
172
|
.join(", ") || "none"}`);
|
|
@@ -202,7 +202,7 @@ export const MODULE_QUESTION = {
|
|
|
202
202
|
: modulesProviding(services.scan, service);
|
|
203
203
|
const chosen = modules.find((module) => module.file === wanted.file && module.exportName === wanted.exportName);
|
|
204
204
|
if (chosen === undefined) {
|
|
205
|
-
throw new
|
|
205
|
+
throw new AvWizardAnswerError(`${spelled(wanted)} is not a module that provides and exports ${service.exportName}; found: ${modules.map(spelled).join(", ") || "none"}`);
|
|
206
206
|
}
|
|
207
207
|
return { file: chosen.file, exportName: chosen.exportName };
|
|
208
208
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aventara/cli",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "Scaffolds an Aventara server: `aventara new` for a new NestJS project, `aventara init` for an existing one.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"typescript": "^5.9.2"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"prebuild": "node scripts/adapter-catalog.generator.ts",
|
|
26
|
+
"prebuild": "node scripts/adapter-catalog.generator.ts && node scripts/agent-skill.generator.ts",
|
|
27
27
|
"build": "node ../../scripts/build/build-output.cleaner.ts dist && tsc -p tsconfig.json --removeComments",
|
|
28
28
|
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
|
|
29
29
|
"test": "vitest run --typecheck --config ../../vitest.config.mts --root .",
|